JS基础篇:数组去重


数组去重有哪些方法?

  1. 利用es6中的set去重,将数组传入到set方法中就可以了
  2. 两层for循环+splice,如果拿每个元素与后面元素进行对比,如果有相同就讲后面重复的元素用splice删除掉
  3. indexof实现去重,创建一个空数组,然后遍历原数组,取出每个值,进行indexof判断,如果等于-1表示不存在,加入到新数组中。
  4. 利用sort进行排序,,然后两两相邻比较,如果不相等就加入到新数组中
  5. 利用includes判断新数组中是否存在该元素,如果不存在就添加
  6. 利用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]

文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
  目录