javascript数组减去另一数组

作者: IOneStar | 来源:发表于2017-10-21 17:00 被阅读112次
    title

    做聊天项目的时候遇要实现这样的一个功能: 邀请新的好友入群;点击邀请好友会弹出一个好友列表,显示你除了在群里面的好友外剩下的所有好友;
    我的思路是取到你所有的好友,然后所有好友中过滤掉已经是群成员的好友

    const users = [
        {
            _id: 1,
            name: '好友1'
        },
        {
            _id: 2,
            name: '好友1'
        },
        {
            _id: 3,
            name: '好友1'
        },
    ];
    const groupMembers = [
        {
            _id: 1,
            name: '好友1'
        },
        {
            _id: 2,
            name: '好友1'
        },
    ]
    

    现在一步一步来看数组的操作

    一,两个数组里的每一项分别为元素时

    const arr1 = ['', '100', '120', '125', '125', '130', '130'];
    
    const arr2 = ['', '120', '125', '125', '130'];
    
    请问如何求得两个数组之差?使得新数组为 arr3 = ['100','130']
    
    

    方法一:

    思路:用for循环比较arr1和arr2的每一项,如果相等,就删除

    const arr1 = ['', '120', '125', '125', '130', '130', '130', '130', '130'];
    
    const arr2 = ['', '120', '125', '130'];
    
    for (let i = arr1.length - 1; i >= 0; i--) {
        a = arr1[i];
        for (let j = arr2.length - 1; j >= 0; j--) {
            b = arr2[j];
            if (a == b) {
                arr1.splice(i, 1);
                arr2.splice(j, 1);
                break;
            }
        }
    }
    
    console.log(arr1);  // ['125','130','130','130','130']
    
    

    方法二:

    思路:将第一个数组存入一个对象,这样就已经去重了;再把第二个数组中的元素当作key从对象中删除。

    const m = {};
    arr1.forEach(function(al){m[al]=al;})
    arr2.forEach(function(bl){delete m[bl];})
    console.dir(Object.keys(m))
    

    方法三:

    思路:声明一个新的数组arr3,比较arr1和arr2,如果arr1中有和arr2不相等的就放入arr3中,用到了es6中关于数组的新方法findIndex(),稍后会详细的介绍;

    const arr1 = ['', '100', '120', '125', '125', '130', '130'];
    const arr2 = ['', '120', '125', '125', '130'];
    const arr3 = [];
    arr1.forEach((a)=>{
        let c = arr2.findIndex(b =>a === b);
        if (c > -1) delete arr2[c];
        else arr3.push(a);
    });
    console.log(arr3)  //['100', '130']
    

    二, arr1中的每一项都是对象,arr2中的每一项都是元素

    const a = [{ id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }];
    const b = [15, 3];
    

    方法一

    a.filter(item => { return !b.includes(item.id); });
    或
    a.filter(item => { return b.indexOf(item.id) === -1; });
     
    

    方法二:

    a=a.filter((x)=>b.every((y)=>y!=x.id))
    

    方法三:

    const a = [{ id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }];
    const b = [15, 3];
    for(index in a){
        if(b.indexOf(a[index]['id'])>=0)
            a.splice(index,1);
    }
    console.log(a);
    或
    const result = a.filter(function (item) {
        return b.indexOf(item.id) < 0;
     })
    

    三,arr1中的每一项都是对象,arr2中的每一项也都是对象,现在回到主题

    const a = [
        {_id: 1},
        {_id: 2},
        {_id: 3},
    ];
    const b = [
        {_id: 2},
        {_id: 4},
    ]
    

    解决方法一:

    const c = a.filter(x => !b.find(y => y._id === x._id)); // [ { _id: 1 }, { _id: 3} ]
    

    解决方法二:

    const c = a.filter(x => b.every(y => y._id !== x._id));
    

    四,介绍一下上面用到的数组实例中的find(), findIndex(), includes()

    find()

    find()用于找出第一个符合条件的数组成员,它的参数是一个回调函数,所有的数组成员依次执行该回调函数,直到找到第一个返回值为true的成员,然后返回该成员,如果没有的话,返回undefined

    [0, 4, -5, -10].find((n) => n < 0);
    // -5
    

    上面代码找出数组中第一个小于0的成员

    [1, 5, 10, 15].find(function(value, index, arr) {
      return value > 9;
    }) 
    // 10
    

    find方法的回调函数可以接受三个参数,当前的值,当前的位置和原数组

    findIndex()

    findIndex()方法的用法与find()方法类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合,则返回-1.

    [1, 5, 10, 15].findIndex(function(value, index, arr) {
      return value > 9;
    }) 
    // 2
    

    两个方法都可以发现NAN,弥补了数组的indexOf方法的不足

    [NaN].indexOf(NaN)
    // -1
    
    [NaN].findIndex(y => Object.is(NaN, y))
    // 0
    

    indexOf方法无法识别数组的NaN成员,但是findIndex方法可以借助Object.is方法做到

    includes()

    Array.prototype.includes方法返回一个布尔值,表达某个数组是否包含给定的值,与字符串的includes方法类似

    [1, 2, 3].includes(2)     // true
    [1, 2, 3].includes(4)     // false
    [1, 2, NaN].includes(NaN) // true
    

    该方法的第二个参数表示搜索的起始位置,默认为0,如果第二个参数为负数,表示倒数的位置;如果这是它大于数组长度(比如第二个参数为-4.但是数组长度为3),则会重置为从0开始

    [1, 2, 3].includes(3, 3);  // false
    [1, 2, 3].includes(3, -1); // true
    

    没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值

    if (arr.indexOf(el) !== -1) {
      // ...
    }
    

    indexOf方法有两个缺点,一是不够语义化.它的含义是找到参数值的第一个出现位置.所以要去比较是否不等于-1,而是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判

    [NaN].indexOf(NaN)
    // -1
    

    includes使用的是不一样的判断算法,就没有这个问题。

    [NaN].includes(NaN)
    // true
    

    参考

    github
    blog

    相关文章

      网友评论

        本文标题:javascript数组减去另一数组

        本文链接:https://www.haomeiwen.com/subject/ytoiuxtx.html