一直对数组的去重都了解的不深,每次都要去百度然后各种调试,今天在网上看到一篇博客,写的很好,不仅让我巩固了很多数组的方法,也解决了工作中遇到的问题。
问题是有一个数组对象,例如:
案例一:
arr = [
{ a: '1', b: 'q1' },
{ a: '2', b: 'q2' },
{ a: '1', b: 'q3' },
{ a: '1', b: 'q4' },
{ a: '2', b: 'q5' },
{ a: '3', b: 'q6' }
]
网上找了很多去重的方法,都是对比了数组中的所有key值和value值,然后来判断是否相同,之前也遇到过这样的去重需求,同样百度到了相应的解决方法:
案例二:
例1:
var arr = [1, 2, 3, 4, 2, 1];
var uniq = function (array) {
var temp = []; //一个新的临时数组
for (var i = 0; i < array.length; i++) {
if (temp.indexOf(array[i]) == -1) {
temp.push(array[i]);
}
}
return temp;
}
uniq(arr); //[1, 2, 3, 4]
例2:
var peoples = [
{id:1,name:'wang'},
{id:2,name:'zhang'},
{id:2,name:'zhang'},
]
//根据id去重
var uniqueOfKey = function(arr) {
var result = [];
var obj = {};
for(var i = 0; i<arr.length; i++){
if(!obj[arr[i].id]){
result.push(arr[i]);
obj[arr[i].id] = true;
}
}
return result;
},
uniqueOfKey(peoples); //[{id:1,name:'wang'},{id:2,name:'zhang'},]
- indexof()
这里遇到了一个 indexof()方法,indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果没有找到匹配的字符串则返回 -1。
而这次遇到的去重是只对比a的value值相同,就去掉,视为重复;
同样在网上找到了代码精简的方法:
var c=arr.reverse().filter(function(item,index){
var _index=arr.findIndex(function(_item){
return item.a == _item.a;
});
return index == _index;
});
c.reverse();
- filter()
这里用到了filter()方法,filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。
和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
下面是几个利于理解该方法的例子,也很实用。
例如,在一个Array中,删掉偶数,只保留奇数
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var a = arr.filter (function( x ) {
return x % 2 !== 0;
})
a = [1, 5, 9, 15]
例如,把一个Array中的空字符串删掉
var arr = ['A', '', 'B', null, undefined, 'C', ' '];
var a = arr.filter (function( x ) {
return x && x.trim(); //$.trim()
函数会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符。如果这些空白字符在字符串中间时,它们将被保留,不会被移除。
})
filter还可以接收回调函数,filter()接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
console.log(element); // 依次打印'A', 'B', 'C'
console.log(index); // 依次打印0, 1, 2
console.log(self); // self就是变量arr
return true;
});
例如案例二中的去重,同样可以用filter来实现遍历:
peopels.filter(function(element, index, self) {
return self.indexOf(element) === index;
})
去除重复元素依靠的是indexOf总是返回第一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。
- findIndex()
这里还用到了一个findIndex方法,findIndex() 方法为数组中的每个元素都调用一次函数执行:
当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
如果没有符合条件的元素返回 -1
注意: findIndex() 对于空数组,函数是不会执行的。
注意: findIndex() 并没有改变数组的原始值。
偶然从语雀上获得一个去重的方法,在此记录一下,该方法配合了ES6语法的set方法。
//数组根据某项的某个值去重复
unique (arr, key) {
const res = new Map();
return arr.filter(a => !res.has(a[key]) && res.set(a[key], 1));
}
set对象是值的集合,元素只会出现一次,即Set中的元素是唯一的。
set方法:
使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}