如何使用另一个数组从一个数组中减去多个对象

3
我想要做的是从数组1中移除在数组2中找到的多个对象,也就是减去,以便最终结果是数组2只包含“jean”对象。
帮帮我!我迷失了。

I tried multiple times code like the following example but it didn't worked.

array1= [{"caracname" : "charles"}, {"caracname" : "kevin"}]
array2= [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}]
            
            array1.forEach(function (k) {
                delete array2[k];
            });
            
            console.log(array2);


可能是比较两个JavaScript数组并删除重复项的重复问题。 - John Ruddell
4个回答

3

使用像Lodash这样的库会更加容易:

var array1 = [{"caracname" : "charles"}, {"caracname" : "kevin"}];
var array2 = [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}];

var array3 = _.differenceWith(array2, array1, _.isEqual);

console.log( JSON.stringify(array3) );

// or 
_.pullAllWith(array2, array1, _.isEqual);

console.log( JSON.stringify(array2) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


如果不使用库,这是一个效率稍低的替代方案(可能无法处理具有多个属性的对象):

var array1 = [{"caracname" : "charles"}, {"caracname" : "kevin"}];
var array2 = [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}];

var j = JSON.stringify, array3 = array2.filter(e => array1.map(j).indexOf(j(e)) < 0);

console.log( j(array3) );


2
这是如何完成此操作的步骤:

以下是具体步骤:

function objectsEqual(o1, o2) {
    return o1.caracname === o2.caracname
}

function subtractArrays(a1, a2) {
    var arr = [];
    a1.forEach((o1) => {
       var found = false;
       a2.forEach((o2) => {
           if (objectsEqual(o1, o2)) {
                found = true;
           }  
       });
       if (!found) {
           arr.push(o1);
       }
    })
    return arr;
}

console.log(subtractArrays(array2, array1));

在 Plunker 中修复了:https://plnkr.co/edit/vA6oWg9R44f6k7ylyFh6?p=preview


控制台显示未定义:https://plnkr.co/edit/CeQgUyhwh3cpYEPwmD30?p=preview - jean
修复并添加了 Plunker。 - Nachshon Schwartz

1
事实证明删除数组元素并不像删除变量那么简单,可以在这里查看。被“删除”的元素并没有真正删除,而是变成了一个undefined值,而数组的长度保持不变。
这里找到一些有用的建议。因此,您可以使用array2的splice方法,根据MDN方便地执行以下操作:

splice()方法通过删除现有元素和/或添加新元素来更改数组的内容。

以下代码片段适用于每个数组中元素的顺序,如下所示:

var arr1 = [{
  "caracname": "charles"
}, {
  "caracname": "kevin"
}];

var arr2 = [{
  "caracname": "charles"
}, {
  "caracname": "jean"
}, {
  "caracname": "kevin"
}];

var tmp1 = "",
    tmp2 = "";

for (var k = 0, key = "", maxLength = arr1.length; k < maxLength; k++) {
  key = Object.keys(arr1[k])[0];
  
  for (var j = 0, maxLength_2 = arr2.length; j < maxLength_2; j++) {
  
    tmp2 = arr2[j][key];
    tmp1 = arr1[k][key];
  
  if (tmp2 === tmp1) {
      arr2.splice(j, 1);
      maxLength_2--; // array2 length now one less
      break;
    }// end if
  }// end inner-for
}// end outer-for

console.log(arr2);


I've revised this example after running the code here, altering some variable names as a result.

作为旁注,你应该使用var或可选的let来声明数组;更多信息这里这里

1
“适当的”对象比较并不容易 https://dev59.com/o3NA5IYBdhLWcg3wKacx (这就是为什么我在我的回答中甚至没有尝试它,而只是比较它们的 JSON 字符串表示,而 Nayish 只比较 caracname 属性的值)。将 JavaScript 粘贴到 TypeScript https://www.typescriptlang.org/play/ 或类似的编辑器中,可能有助于注意一些问题(不确定是否将 Object.keys 中的数组用作字符串 [key] 是有意义的)。 - Slai
@Slai 谢谢你提供的信息。我已经修复了代码,现在变量 key 保存了一个字符串值。我测试了一下代码,在 TypeScript 网站上运行时似乎没问题了。 - slevy1

0

使用此代码:[由@slevy1建议]

var array1= [{"caracname" : "charles"}, {"caracname" : "kevin"}]
var array2= [{"caracname" : "charles"}, {"caracname" : "kevin"}, {"caracname" : "jean"}]

array1.forEach(function (k) {
    var index = array1.valueOf(k);
    array2.splice(index, 1);
});

array2.forEach(function (o) {
    console.log(o.caracname);
});

CodePen链接


我在这里运行了你的代码 https://codepen.io/anon/pen/KXGZPv?editors=1111,但没有得到预期的结果。 - slevy1
嗨@slevy1,感谢你的努力。我已经编辑(修复)了我的代码,现在它可以工作了。请再次测试,兄弟。 - fatih
@Fatih index 不是一个数字(尝试使用 console.log(index))而且 array2.splice 只会移除第一个项目。 - Slai
感谢@slevy1的建议。 - fatih

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