JavaScript从一个对象数组中获取不在另一个数组中的元素

27

我是JavaScript编程的新手,我有两个对象数组,它们的结构如下:

myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

我需要获取包含关键字foo的值的两个单独数组,第一个基于关键字foo的值含有第一个数组中但不在第二个数组中的值,第二个数组含有在mySecondObjArray中但不在myFirstObjArray 中的值。

是否有方法可以在不使用方式的情况下实现这一点?

for(i=0;i<myFirstObjArray.length;i++)
   for(j=0;j<mySecondObjArray .length;j++)
      {...build first array here}

for(i=0;i<mySecondObjArray .length;i++)
   for(j=0;j<myFirstObjArray.length;j++)
      {...build second array here}

? 也许我的问题是一个我没有找到的重复问题,所以请温柔一点。

期望输出:

firstArray = [{foo: 1}, {foo: 3}];
secondArray = [{foo: 2}, {foo: 5}];

add your expected output here - Muhammad Usman
@GeorgeBailey 更新了我的问题。 - LAffair
@Dana:我添加了ES5的答案,以支持所有浏览器,包括IE。 - Jayamurugan
在大多数编程语言中,这被称为“数组差异”之类的东西。 - Martijn
5个回答

24

您可以通过根据另一个数组的元素设置条件来简单地过滤一个数组的元素,例如:

var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}],
    
    firstArray  = myFirstObjArray.filter(o=> !mySecondObjArray.some(i=> i.foo === o.foo));
    
    secondArray  = mySecondObjArray.filter(o=> !myFirstObjArray.some(i=> i.foo === o.foo));
    
    console.log(firstArray.map(o=> {return {'foo' :  o.foo}}))
    console.log(secondArray.map(o=> {return {'foo' :  o.foo}}))

Ps:

some() 方法测试数组中是否有至少一个元素通过提供的函数实现的测试。我添加了一个函数,仅检查另一个数组中是否存在具有相同值的 foo 属性,以便能够从第一个数组中进行筛选。

最后,您可以使用 .map 来过滤所需的键值对。

希望这讲得通。

了解更多关于 .somefilter 的内容。


2
第一个数组应该只包含 foo 属性,所以 OP 可能需要了解一下 map - barbsan
没有提供预期的输出。 - Falco
这对我有帮助,谢谢。 - Cuado

10
这里是一个只使用filter和带有foo属性的map的小型解决方案。

const myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
const mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

const exclude = (arr1, arr2) => arr1.filter(o1 => arr2.map(o2 => o2.foo).indexOf(o1.foo) === -1);

console.log(exclude(myFirstObjArray, mySecondObjArray));
console.log(exclude(mySecondObjArray, myFirstObjArray));


更倾向于使用 includes 而不是 indexOf - Benjamin Gruenbaum

2

不使用箭头函数的ES5:

var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}],
    
    firstArray  = myFirstObjArray.filter(function(o) { return !mySecondObjArray.some(function(i) { return i.foo === o.foo})});
     
    secondArray  = mySecondObjArray.filter(function(o) { return !myFirstObjArray.some(function(i) { return i.foo === o.foo})});
    
    console.log(firstArray)
    console.log(secondArray)


1
你可以通过查找进行筛选。

const unique = a => o => !a.some(({ foo }) => o.foo === foo);

var first = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}],
    second = [{foo: 2}, {foo: 4}, {foo: 5}],
    uniqueFirst = first.filter(unique(second)),
    uniqueSecond = second.filter(unique(first));
    
console.log(uniqueFirst);
console.log(uniqueSecond);
.as-console-wrapper { max-height: 100% !important; top: 0; }


1
你可以创建一个可重用的函数来避免代码重复。只需切换到函数参数。还要注意内部循环是简单的for循环,这样我们就可以使用break避免不必要的检查。

var firstArray = [];
var secondArray = [];
var myFirstObjArray = [{foo: 1, bar: 1}, {foo: 3, bar: 3}, {foo: 4, bar: 5}];
var mySecondObjArray = [{foo: 2}, {foo: 4}, {foo: 5}];

function difference(myFirstObjArray, mySecondObjArray){
  var firstArray = [];
  myFirstObjArray.forEach((obj)=>{
   var match = false;
   for(var i=0; i<mySecondObjArray.length; i++){
     var secondObj = mySecondObjArray[i];
     if(obj.foo === secondObj.foo){
       match = true;
       break;
     }
   }
   if(!match){
     firstArray.push({'foo': obj.foo});
   }
  });
  return firstArray;
}


console.log(difference(myFirstObjArray, mySecondObjArray));

console.log(difference(mySecondObjArray, myFirstObjArray));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接