We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
数组去重在面试和工作中都是比较容易见到的问题。
这篇文章主要是来测试多个方法,对下面这个数组的去重结果进行分析讨论。如果有不对的地方,还请大家指出。
const arr = [ 1, 1, "1", "1", 0, 0, "0", "0", true, false, "true", "false", "a", "A", undefined, undefined, "undefined", null, null, 'null', NaN, NaN, +0, -0, new String("1"), new String("1"), Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], [] ];
console.log(1 == "1"); // true console.log(1 === "1"); // false console.log(0 == "0"); // true console.log(0 === "0"); // false console.log(0 == +0); // true console.log(0 === +0); // true console.log(0 == -0); // true console.log(0 === -0); // true console.log(+0 == -0); // true console.log(+0 === -0); // true console.log(0 == false); // true console.log(0 === false); // false console.log(0 == undefined); // false console.log(0 === undefined); // false console.log(0 == null); // false console.log(0 === null); // false console.log(1 == true); // true console.log(1 === true); // false console.log(undefined == null); // true console.log(undefined === null); // false console.log(NaN == NaN); // false console.log(NaN === NaN); // false console.log(new String("1") == new String("1")); // false console.log(new String("1") === new String("1")); // false Object.prototype.toString.call(new String('1')) // '[object String]' console.log(/a/ == /a/); // false console.log(/a/ === /a/); // false Object.prototype.toString.call(/a/); //'[object RegExp]' console.log(Symbol(1) == Symbol(1)); // false console.log(Symbol(1) === Symbol(1)); // false console.log({} == {}); // false console.log({} === {}); // false console.log([] == []); // false console.log([] === []); // false
接下来,我们看看下面多个去重方法,对以上特殊类型的去重效果。
// 暴力解法一 function unique(array) { if (!Array.isArray(array)) { console.log("type error!"); return; } const res = [array[0]]; let arrLen = array.length; let resLen = res.length; for (let i = 0; i < arrLen; i++) { let flag = true; for (let j = 0; j < resLen; j++) { if (array[i] === res[j]) { flag = false; break; } } if (flag) { res.push(array[i]); resLen = res.length; } } return res; } // [1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
输出:
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
输出结果说明:
+0
-0
0
NaN
new String("1")
/a/
{}
[]
Symbol(1)
暴力解法,简单易理解,兼容性好。去重结果如上所示。
// ES6 Array.from + Set 方法一 function unique(array) { if (!Array.isArray(array)) { console.log('type error!') return } return Array.from(new Set(array)) } // ES6 点运算 + Set 方法二 function unique1(array) { if (!Array.isArray(array)) { console.log('type error!') return } return [...new Set(arr)] } // ES6 箭头函数 + 点运算 + Set 方法三 const unique2 = (array) => { if (!Array.isArray(array)) { console.log('type error!') return } return [...new Set(arr)] } // ES6 Map + ES5 filter 方法四 function unique3(array) { if (!Array.isArray(array)) { console.log('type error!') return } const seen = new Map() return array.filter((a) => !seen.has(a) && seen.set(a, 1)) }
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
利用indexOf检测元素在新数组是否存在
// indexOf + forEach 利用indexOf检测元素在新数组是否存在 function unique(array) { if (!Array.isArray(array)) { console.log('type error!') return } const newArr = []; array.forEach((el) => { if (newArr.indexOf(el) === -1) { newArr.push(el); } }); return newArr; }
利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等
// indexOf + forEach 利用indexOf检测元素在新数组是否存在 function unique(array) { if (!Array.isArray(array)) { console.log('type error!') return } return array.filter((item, index) => { return array.indexOf(item) === index; }); } console.log([NaN].indexOf(NaN)); // -1
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
重点:
console.log([NaN].indexOf(NaN)); // -1
sort()方法主要是用于对数组进行排序,默认情况下该方法是将数组元素转换成字符串,然后按照ASC码进行排序
// sort()方法不支持Symbol,Symbol不支持转换成字符串 function unique(array) { if (!Array.isArray(array)) { console.log("type error!"); return; } const sortArr = array.sort(); const newArr = []; sortArr.forEach((el, i) => { if (sortArr[i] !== sortArr[i - 1]) { newArr.push(el); } }); return newArr; }
[[], [], /a/, /a/, 0, "0", 0, 1, "1", String {'1'}, String {'1'}, "A", NaN, NaN, {}, {}, "a", false, "false", null, "null", true, "true", "undefined", undefined]
"0"
Symbol
利用includes()方法检查新数组是否包含原数组的每一项
// 利用includes()方法检查新数组是否包含原数组的每一项 function unique(array) { if (!Array.isArray(array)) { console.log("type error!"); return; } const newArr = []; array.forEach((el) => { newArr.includes(el) ? newArr : newArr.push(el); }); return newArr; }
// 利用includes()方法检查新数组是否包含原数组的每一项 function unique(array) { if (!Array.isArray(array)) { console.log("type error!"); return; } return array.reduce((pre, cur) => { !pre.includes(cur) && pre.push(cur); return pre; }, []); }
利用了对象的key不可以重复的特性来进行去重
// 利用了对象的key不可以重复的特性来进行去重 function unique(array) { if (!Array.isArray(array)) { console.log("type error!"); return; } const obj = {}; const newArr = []; array.forEach((val) => { if (!obj[typeof val + JSON.stringify(val)]) { // 将对象序列化之后作为key来使用 obj[typeof val + JSON.stringify(val)] = 1; newArr.push(val); } }); return newArr; }
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, Symbol(1), {}, []]
将不该去重的Symbol去重了;将两个/a/全部删除了
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []
上面只是简单结果的去重总结,具体的去重选择还需要根据我们业务场景来选择去重方法。
可以去Github仓库查看演示代码
主要是日常对每个进阶知识点的摸透,跟着大佬一起去深入了解JavaScript的语言艺术。
后续会一直更新,希望各位看官不要吝啬手中的赞。
❤️ 感谢各位的支持!!!
❤️ 如果有错误或者不严谨的地方,请务必给予指正,十分感谢!!!
❤️ 喜欢或者有所启发,欢迎 star!!!
【跟着大佬学JavaScript】之数组去重(结果对比)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
数组去重在面试和工作中都是比较容易见到的问题。
这篇文章主要是来测试多个方法,对下面这个数组的去重结果进行分析讨论。如果有不对的地方,还请大家指出。
特殊类型
接下来,我们看看下面多个去重方法,对以上特殊类型的去重效果。
代码一(暴力解法)
输出:
输出结果说明:
+0
、-0
、0
NaN
不去重new String("1")
、/a/
、{}
不去重[]
不去重Symbol(1)
不去重暴力解法,简单易理解,兼容性好。去重结果如上所示。
代码二(ES6)
输出:
输出结果说明:
+0
、-0
、0
NaN
new String("1")
、/a/
、{}
不去重[]
不去重Symbol(1)
不去重代码三(indexOf + forEach)
输出:
输出结果说明:
+0
、-0
、0
NaN
不去重new String("1")
、/a/
、{}
不去重[]
不去重Symbol(1)
不去重代码四(indexOf + filter)
输出:
输出结果说明:
+0
、-0
、0
NaN
都会被删除new String("1")
、/a/
、{}
不去重[]
不去重Symbol(1)
不去重重点:
代码五(sort排序,不支持Symbol)
输出:
输出结果说明:
+0
、-0
、0
、"0"
位置不同会导致去重不了NaN
不去重new String("1")
、/a/
、{}
不去重[]
不去重Symbol
的数组代码六(includes)
输出:
输出结果说明:
+0
、-0
、0
NaN
new String("1")
、/a/
、{}
不去重[]
不去重Symbol
不去重代码七(includes+reduce)
输出:
输出结果说明:
+0
、-0
、0
NaN
new String("1")
、/a/
、{}
不去重[]
不去重Symbol
不去重代码八(对象key)
输出:
输出结果说明:
+0
、-0
、0
NaN
new String("1")
、{}
;两个/a/
全部被删除了[]
Symbol
将不该去重的
Symbol
去重了;将两个/a/
全部删除了总结
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
[[], [], /a/, /a/, 0, "0", 0, 1, "1", String {'1'}, String {'1'}, "A", NaN, NaN, {}, {}, "a", false, "false", null, "null", true, "true", "undefined", undefined]
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []]
[1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, Symbol(1), {}, []]
上面只是简单结果的去重总结,具体的去重选择还需要根据我们业务场景来选择去重方法。
演示地址
可以去Github仓库查看演示代码
跟着大佬学系列
主要是日常对每个进阶知识点的摸透,跟着大佬一起去深入了解JavaScript的语言艺术。
后续会一直更新,希望各位看官不要吝啬手中的赞。
❤️ 感谢各位的支持!!!
❤️ 如果有错误或者不严谨的地方,请务必给予指正,十分感谢!!!
❤️ 喜欢或者有所启发,欢迎 star!!!
参考
原文地址
【跟着大佬学JavaScript】之数组去重(结果对比)
The text was updated successfully, but these errors were encountered: