js 如何判断两个数组的对象是否相同?

var arr = [
    {id:1,name:"小明"},
    {id:2,name:"小红"},
    {id:3,name:"小花"},
    {id:4,name:"小强"}
]

var arr2 = [
    {id:2,name:"小红"},
    {id:3,name:"小花"},
    {id:4,name:"小强"}
]

我用的方法是:
var list = [];
for(var i=0;i < arr.length; i++){
    arr2.indexOf(arr[i]) === -1 ? list.push(arr[i]): 0;
}

结果就是  都是 -1

所以有什么方法简便的方法比较这两个吗?

阅读 4.1k
1 个回答

这个问题的本质是要找两个数组的交集,而且不是按引用比较,是按对象属性比较。题主之所以找不出来,是因为 indexOf 是按引用来找的,不是按对象属性来匹配的,两个字面量对象肯定是不同的引用。

如果要自己写个代码,涉及到深度比较的问题,处理起来代码理比较大,建议用现成的,比如 Lodash 提供的

_.equals 可以直接用来比较两个对象(或数组)是否相同。

如果按题主循环的思路来做,是这样:

const list = [];
for (var i = 0; i < arr.length; i++) {
    for (var j = 0; j < arr2.length; j++) {
        if (_.isEqual(arr[i], arr2[j])) {
            list.push(arr[i]);
        }
    }
}

不能用 includes 或者 indexOf 来判断,因为它是按引用对比的,不是按对象属性匹配的。

这个循环可以使用函数式写法简少代码(代码简化了,但理解可能更难一些)

const result = arr.filter(it => arr2.find(it2 => _.isEqual(it, it2)));

这个过程可以用 Lodash 的 intersection(交集)来实现。

_.intersection 可以用来取两个集合的交集,它有两个扩展,_.intersectionBy_.intersectionWith

像题目上这个需要,可以用如下代码找出来

const r = _.intersectionWith(arr, arr2, _.isEqual);

// [ { id: 2, name: '小红' }, { id: 3, name: '小花' }, { id: 4, name: '小强' } ]

如果想知道具体实现过程,可以去看 Lodash 的源代码。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题