摘要:JavaScript面试题数组去重,参考冴羽的博客再次修改
方法一
思路:
1.构建一个新的数组存放结果
2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
3.若结果数组中没有该元素,则存到结果数组中
1 | Array.prototype.unique1_1 = function () { |
使用indexOf
简化内层的循环:
1 | Array.prototype.unique1_2 = function () { |
使用filter
简化外层循环:
1 | Array.prototype.unique1_3 = function () { |
方法二
思路:
1.将目标组进行排序后存储到一个新数组中
2.检查排序后新数组中的第i个元素与结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
3.如果不相同,则将该元素存入结果数组中
1 | Array.prototype.unique2_1 = function () { |
使用filter
简化:
1 | Array.prototype.unique2_2 = function () { |
现在数组有两种情况:有序和无序。结合前两种方法,为了提高去重效率可以这样写:
1 | Array.prototype.unique2_3 = function (isSorted) { // 有序数组为true,无序为false |
如果还有不区分字母大小写等需求,可以先将所有字符转小写再按照前面的方法处理,但这样先遍历一次数组的效率并不高。想要在去重比较的同时进行处理:
1 | Array.prototype.unique12_4 = function (isSorted, callback) { |
方法三
思路:
1.创建一个新的数组存放结果
2.创建一个空对象
3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复(对象没有这个属性),则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为true,存入到第2步创建的对象中。
1 | Array.prototype.unique3_1 = function () { |
使用filter
简化:
1 | Array.prototype.unique3_2 = function () { |
数组值的类型不都一样的话会程序有一点问题:数字 1 和字符串”1”会认为是一个属性,因为对象的键都是字符串。这时就需要区分两者,可以添加特定的字符串加以区别。比如添加上各自的类型:
1 | Array.prototype.unique3_3 = function () { |
但是,依然无法正确区分出两个对象,因为 typeof item +item 的结果都是object[object Object]
,可以使用JSON.stringify
将对象序列化加以区别:
1 | Array.prototype.unique3_4 = function () { |
如果要统计每个值重复的次数,需要进行修改,用参数count来判断返回什么值
1 | Array.prototype.unique3_5 = function (count) { |
方法四
利用 Set 结构的成员值不能重复的特点来实现数组去重的效果
1 | Array.prototype.unique4_1 = function(){ |
还可以利用Map的键名可以是各种类型的特点来实现
1 | Array.prototype.unique4_2 = function() { |
总结
使用这样一个数组 array 进行验证:
1 | var array = [1, 1, "1", "1", null, null, undefined, undefined, new String("1"), new String("1"), /a/, /a/, NaN, NaN]; |
方法 | 结果 | 结论 |
1_1:for循环 | [1, “1”, null, undefined, String, String, /a/, /a/, NaN, NaN] | 对象和NaN不去重 |
1_2:indexOf | [1, “1”, null, undefined, String, String, /a/, /a/, NaN, NaN] | 对象和 NaN 不去重 |
1_3:filter + indexOf | [1, “1”, null, undefined, String, String, /a/, /a/] | 对象不去重 NaN 被忽略 |
2_1:sort | [/a/, /a/, “1”, 1, String, 1, String, NaN, NaN, null, undefined] | 对象、NaN、数字1不去重 |
2_2:sort + filter | [/a/, /a/, “1”, 1, String, 1, String, NaN, NaN, null, undefined] | 对象、NaN、数字1不去重 |
3_4:优化后的键值对 | [1, “1”, null, undefined, String, /a/, NaN] | 全部去重 |
4_1:Set(node) | [1, “1”, null, undefined, [String: “1”], [String: “1”], /a/, /a/, NaN] | 对象不去重 |
注意:
1.indexOf使用strict equality(无论是===,还是triple-equals操作符都基于同样的方法)进行判断 searchElement与数组中包含的元素之间的关系
2.NaN和undefined都可以被存储在Set中,尽管NaN !== NaN,但NaN之间仍被视为相同的值
3.优化后的计数:
1 | console.log(array.unique3_5(true)); |