【跟着大佬学JavaScript】之数组去重(结果对比)
前言
数组去重在面试和工作中都是比较容易见到的问题。
这篇文章主要是来测试多个方法,对下面这个数组的去重结果进行分析讨论。如果有不对的地方,还请大家指出。
1 | 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/, [], [] ]; |
特殊类型
1 | console.log(1 == "1"); // true |
接下来,我们看看下面多个去重方法,对以上特殊类型的去重效果。
代码一(暴力解法)
1 | // 暴力解法一 |
输出:
1 | [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)
1 | // ES6 Array.from + Set 方法一 |
输出:
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/, [], []] |
输出结果说明:
- 去重
+0
、-0
、0
- 去重
NaN
- 对象
new String("1")
、/a/
、{}
不去重 - 数组
[]
不去重 Symbol(1)
不去重
代码三(indexOf + forEach)
利用 indexOf 检测元素在新数组是否存在
1 | // indexOf + forEach 利用indexOf检测元素在新数组是否存在 |
输出:
1 | [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)
不去重
代码四(indexOf + filter)
利用 indexOf 检测元素在数组中第一次出现的位置是否和元素现在的位置相等
1 | // indexOf + forEach 利用indexOf检测元素在新数组是否存在 |
输出:
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/, [], []] |
输出结果说明:
- 去重
+0
、-0
、0
- 两个
NaN
都会被删除 - 对象
new String("1")
、/a/
、{}
不去重 - 数组
[]
不去重 Symbol(1)
不去重
重点:
1 | console.log([NaN].indexOf(NaN)); // -1 |
代码五(sort 排序,不支持 Symbol)
sort()方法主要是用于对数组进行排序,默认情况下该方法是将数组元素转换成字符串,然后按照 ASC 码进行排序
1 | // sort()方法不支持Symbol,Symbol不支持转换成字符串 |
输出:
1 | [[], [], /a/, /a/, 0, "0", 0, 1, "1", String {'1'}, String {'1'}, "A", NaN, NaN, {}, {}, "a", false, "false", null, "null", true, "true", "undefined", undefined] |
输出结果说明:
+0
、-0
、0
、"0"
位置不同会导致去重不了NaN
不去重- 对象
new String("1")
、/a/
、{}
不去重 - 数组
[]
不去重 - sort()方法不支持处理含有
Symbol
的数组
代码六(includes)
利用 includes()方法检查新数组是否包含原数组的每一项
1 | // 利用includes()方法检查新数组是否包含原数组的每一项 |
输出:
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/, [], []] |
输出结果说明:
- 去重
+0
、-0
、0
- 去重
NaN
- 对象
new String("1")
、/a/
、{}
不去重 - 数组
[]
不去重 Symbol
不去重
代码七(includes+reduce)
利用 includes()方法检查新数组是否包含原数组的每一项
1 | // 利用includes()方法检查新数组是否包含原数组的每一项 |
输出:
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/, [], []] |
输出结果说明:
- 去重
+0
、-0
、0
- 去重
NaN
- 对象
new String("1")
、/a/
、{}
不去重 - 数组
[]
不去重 Symbol
不去重
代码八(对象 key)
利用了对象的 key 不可以重复的特性来进行去重
1 | // 利用了对象的key不可以重复的特性来进行去重 |
输出:
1 | [1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, Symbol(1), {}, []] |
输出结果说明:
- 去重
+0
、-0
、0
- 去重
NaN
- 去重对象
new String("1")
、{}
;两个/a/
全部被删除了 - 去重数组
[]
- 去重
Symbol
将不该去重的Symbol
去重了;将两个/a/
全部删除了
总结
方法 | 结果 | 说明 |
---|---|---|
for 循环暴力解法 | [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.去重+0、-0、0; 2.NaN 不去重;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
ES6 解法 | [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.去重+0、-0、0; 2.去重 NaN;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
indexOf + forEach | [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.去重+0、-0、0; 2.NaN 不去重;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
indexOf + filter | [1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', String {'1'}, String {'1'}, Symbol(1), Symbol(1), {}, {}, /a/, /a/, [], []] |
1.去重+0、-0、0; 2.两个 NaN 都会被删除;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
sort 排序,不支持 Symbol | [[], [], /a/, /a/, 0, "0", 0, 1, "1", String {'1'}, String {'1'}, "A", NaN, NaN, {}, {}, "a", false, "false", null, "null", true, "true", "undefined", undefined] |
1.+0、-0、0、”0”位置不同会导致去重不了 2.NaN 不去重;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.sort()方法不支持处理含有 Symbol 的数组; |
includes | [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.去重+0、-0、0; 2.去重 NaN;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
includes+reduce | [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.去重+0、-0、0; 2.去重 NaN;3.对象 new String(“1”)、/a/、{}不去重;4.数组[]不去重;5.Symbol(1)不去重; |
对象 key | [1, '1', 0, '0', true, false, 'true', 'false', 'a', 'A', undefined, 'undefined', null, 'null', NaN, String {'1'}, Symbol(1), {}, []] |
1.去重+0、-0、0; 2.去重 NaN;3.去重对象 new String(“1”)、{};两个/a/全部被删除了;4.去重数组[];5.去重 Symbol |
上面只是简单结果的去重总结,具体的去重选择还需要根据我们业务场景来选择去重方法。
演示地址
可以去Github 仓库查看演示代码
跟着大佬学系列
主要是日常对每个进阶知识点的摸透,跟着大佬一起去深入了解 JavaScript 的语言艺术。
后续会一直更新,希望各位看官不要吝啬手中的赞。
❤️ 感谢各位的支持!!!
❤️ 如果有错误或者不严谨的地方,请务必给予指正,十分感谢!!!
❤️ 喜欢或者有所启发,欢迎 star!!!
参考
原文地址
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 易函123!
评论