数组去重有哪些方法?
- 利用es6中的set去重,将数组传入到set方法中就可以了
- 两层for循环+splice,如果拿每个元素与后面元素进行对比,如果有相同就讲后面重复的元素用splice删除掉
- indexof实现去重,创建一个空数组,然后遍历原数组,取出每个值,进行indexof判断,如果等于-1表示不存在,加入到新数组中。
- 利用sort进行排序,,然后两两相邻比较,如果不相等就加入到新数组中
- 利用includes判断新数组中是否存在该元素,如果不存在就添加
- 利用filter 如果找的那个元素的索引和遍历的当前索引一直,表示只有一个 ,则添加
纯数组去重
方法一:利用ES6 Set去重(ES6中最常用)
function unique(arr) {
return Array.from(new Set(arr))
}
var arr1 = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, 0, 'a', {}, {}]
//{}没有去重
如果不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。
方法二:利用for嵌套for,然后splice去重(ES5中最常用)
function unique(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [1, 2, 'true', 'b', 15, false, undefined, NaN, NaN, 'a', {}, {}]
//NaN和{}没有去重,2个null都去掉了
方法三:利用indexOf
去重
function unique(arr) {
if (!Array.isArray(arr)) {
console.log("type error!")
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) //[1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, NaN, 0, 'a', {}, {}]
//NaN,{}没有去重
新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。
方法四:利用sort()
function unique(arr) {
if (!Array.isArray(arr)) {
console.log("type error!")
return
}
arr = arr.sort();
var array = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
array.push(arr[i])
}
}
return array;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) //[0, 1, 15, 2, NaN, NaN, {}, {}, 'a', 'b', false, null, 'true', true, undefined]
//NaN,{}没有去重
利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。
方法五:利用对象的属性不能相同的特点进行去重
function unique(arr) {
if (!Array.isArray(arr)) {
console.log("type error!")
return
}
var array = [];
var obj = {};
for (var i = 1; i < arr.length; i++) {
if (!obj[arr[i]]) {
array.push(arr[i])
obj[arr[i]] = 1
} else {
obj[arr[i]]++
}
}
return array;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [2, 1, 'true', 'b', 15, false, undefined, null, NaN, 0, 'a', {}]
//2个true都去掉了,NaN,{}去重
方法六:利用includes
function unique(arr) {
if (!Array.isArray(arr)) {
console.log("type error!")
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (!array.includes(arr[i])) { //includes 检测数组是否有这个值
array.push(arr[i])
}
}
return array;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) //[1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, 0, 'a', {}, {}]
//{}没有去重
方法七:利用hasOwnProperty
function unique(arr) {
var obj = {};
return arr.filter((item, index, arr) => {
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) //[1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, 0, 'a', {}]
//所有的都去重了
利用hasOwnProperty 判断是否存在对象属性
扩展:hasOwnProperty()
语法:obj.hasOwnProperty(prop) ,参数prop为字符串
- js原生方法, object.prototype.hasOwnProperty()
- 返回值: 返回一个布尔值, 判断该对象是否含有指定属性, 不包含继承来的属性
var obj = new Object();
obj.prop = 'wang';
obj.hasOwnProperty("prop") //true
delete o.prop;
obj.hasOwnProperty("prop") //false
方法八:利用filter
function unique(arr) {
var obj = {};
return arr.filter((item, index, arr) => {
return arr.indexOf(item, 0) === index;
})
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [1, 2, 'true', 'b', true, 15, false, undefined, null, 0, 'a', {}, {}]
//2个NaN都去掉了,{}没有去重
方法九:利用递归去重
只适合纯数字数组,不适合字符串数组
function unique(arr) {
var array = arr;
var len = array.length;
array.sort(function(a, b) { //排序后更加方便去重
return a - b;
})
function loop(index) {
if (index >= 1) {
if (array[index] === array[index - 1]) {
array.splice(index, 1);
}
loop(index - 1); //递归loop,然后数组去重
}
}
loop(len - 1);
return array;
}
var arr1 = [1, 2, 1, 'true', 'b', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
var arr2 = [1, 2, 1, 4, 5, 2]
console.log(unique(arr1)) // [1, 2, 'true', 'b', 'true', false, null, 0, true, 15, NaN, NaN, 'a', {}, {}, undefined]
console.log(unique(arr2)) //[1, 2, 4, 5]
方法十:利用Map
数据结构去重
function unique(arr) {
let map = new Map();
let array = new Array(); //数组用于返回结果
for (var i = 0; i < arr.length; i++) {
if (map.has(arr[i])) { //如果有该key值
map.set(arr[i], true);
} else {
map.set(arr[i], false);
array.push(arr[i])
}
}
return array;
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, 0, 'a', {}, {}]
//{}没有去重
创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
方法十一:利用reduce
+includes
function unique(arr) {
return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], [])
}
var arr = [1, 2, 1, 'true', 'b', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 0, 0, 'a', 'a', {}, {}]
console.log(unique(arr)) // [1, 2, 'true', 'b', true, 15, false, undefined, null, NaN, 0, 'a', {}, {}]
//{}没有去重
对象数组去重
方法一:对象访问属性
采用对象访问属性的方法,判断属性值是否存在,如果不存在就添加。
var arr = [{
key: '01',
value: '乐乐'
}, {
key: '02',
value: '博博'
}, {
key: '03',
value: '淘淘'
},{
key: '04',
value: '哈哈'
},{
key: '01',
value: '乐乐'
}];
// 方法1:利用对象访问属性的方法,判断对象中是否存在key
var result = [];
var obj = {};
for(var i =0; i<arr.length; i++){
if(!obj[arr[i].key]){
result.push(arr[i]);
obj[arr[i].key] = true;
}
}
console.log(result); // [{key: "01", value: "乐乐"},{key: "02", value: "博博"},{key: "03", value: "淘淘"},{key: "04", value: "哈哈"}]
方法二:reduce
方法
采用数组中的reduce方法,遍历数组,也是通过对象访问属性的方法
// 方法2:利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值
var obj = {};
arr = arr.reduce(function(item, next) {
obj[next.key] ? '' : obj[next.key] = true && item.push(next);
return item;
}, []);
console.log(arr); // [{key: "01", value: "乐乐"},{key: "02", value: "博博"},{key: "03", value: "淘淘"},{key: "04", value: "哈哈"}]
取出两个纯数组的不同元素
// 取出两个数组的不同元素
var arr1 = [0, 1, 2, 3, 4, 5];
var arr2 = [0, 4, 6, 1, 3, 9];
function getArrDifference(arr1, arr2) {
return arr1.concat(arr2).filter(function(v, i, arr) {
return arr.indexOf(v) === arr.lastIndexOf(v);
});
}
console.log(getArrDifference(arr1, arr2)); //输出:(4) [2, 5, 6, 9]
console.log(getArrDifference(arr2, arr1)); //输出:(4) [6, 9, 2, 5]
取出两个纯数组的不相同元素
var arr1 = [0, 1, 2, 3, 4, 5];
var arr2 = [0, 4, 6, 1, 3, 9];
function getArrEqual(arr1, arr2) {
let newArr = [];
for (let i = 0; i < arr2.length; i++) {
for (let j = 0; j < arr1.length; j++) {
if (arr1[j] === arr2[i]) {
newArr.push(arr1[j]);
}
}
}
return newArr;
}
console.log(getArrEqual(arr1, arr2)); //输出:(4) [0, 4, 1, 3]
console.log(getArrEqual(arr2, arr1)); //输出:(4) [0, 1, 3, 4]