简体   繁体   English

通过比较具有不同元素的两个对象数组来过滤和删除项目

[英]Filter and delete items by comparing two arrays of objects with different elements

I have two arrays 我有两个数组

arr1 = [{path: "path1"}, {path: "path2"}];
arr2 = [{path: "path1"}];

First, I want to find the element that is removed from arr1 (in this case its path1 object) by comparing two arrays and manipulate the first array or overwrite it by removing the item. 首先,我想通过比较两个数组来查找从arr1中删除的元素(在本例中为其path1对象),并操纵第一个数组或通过删除该项覆盖它。 In this case the expected array is 在这种情况下,预期的数组是

expArray = [{path: "path2"}]

I have tried using array.filter method. 我试过使用array.filter方法。

var filteredElements = arr1 .filter(function(obj) {
    return !arr2 .some(function(obj2) {
        return obj.Path === obj2.Path;
    });    
});

But it only gives the list of element that are different, but does not support removing the element from the array. 但是它仅提供了不同的元素列表,但不支持从数组中删除该元素。 Is there a way to do this using underscore or traditional way ? 有没有办法使用下划线或传统方式做到这一点?

You have a typo of Path vs path . 您有Path vs path的错字。 The code works with this change. 该代码适用于此更改。

 var arr1 = [{ path: "path1" }, { path: "path2" }], arr2 = [{ path: "path1" }], filteredElements = arr1.filter(function(obj) { return !arr2.some(function(obj2) { return obj.path === obj2.path; // ^ ^ }); }); console.log(filteredElements); 

If you like to mutate arr1 you could splice unwanted elements and because this changes the length, you could iterate from the end. 如果您想对arr1进行突变,则可以拼接不需要的元素,并且由于这会改变长度,因此可以从末尾进行迭代。

 var arr1 = [{ path: "path1" }, { path: "path2" }], arr2 = [{ path: "path1" }], i = arr1.length; while (i--) { if (arr2.some(({ path }) => arr1[i].path === path)) { arr1.splice(i, 1); } } console.log(arr1); 

You can use Array#splice to remove the element from an existing array. 您可以使用Array#splice从现有阵列中删除元素。

 let arr1 = [{ path: "path1" }, { path: "path2"}]; let arr2 = [{ path: "path1" }]; // get length of array for iteration let l = arr1.length; // iterate from end to start to avoid skipping index after removing an element while (l--) { // check elemnt present in the array if (arr2.some(obj => obj.path === arr1[l].path)) // remove the element arr1.splice(l, 1); } console.log(arr1); 

I believe you just typed the path property as Path and it is returning an empty array. 我相信您只是将path属性键入为Path并且它返回一个空数组。

The code working: 工作的代码:

var arr1 = [{path: "path1"}, {path: "path2"}];
var arr2 = [{path: "path1"}];

var filteredElements = arr1.filter(function(obj) {
  return !arr2.some(function(obj2) {
    return obj.path === obj2.path;
  });
});

If you want to overwrite the first array, just replace filteredElements by arr1 . 如果要覆盖第一个数组,只需用arr1替换filteredElements

you can use map, 你可以用地图

 let arr1 = [{ path: "path1" }, { path: "path2"}]; const arr2 = [{ path: "path1" }]; const itemsToRemove = arr2.map(a => a.path); arr1 = arr1.filter(a => !itemsToRemove.includes(a.path)); console.log(arr1); 

filter and reassign the array values. 过滤并重新分配数组值。

Another way to handle this is to separate the logic for testing whether two items are equal from the process of filtering the data. 处理此问题的另一种方法是,从筛选数据的过程中分离出用于测试两项是否相等的逻辑。 Here, keep is a very simple higher-order function. 在这里, keep是一个非常简单的高阶函数。 We pass it a function that reports whether two object have the same path property and get back a function on two arrays. 我们传递给它一个函数,该函数报告两个对象是否具有相同的path属性,并在两个数组上返回一个函数。

We then simply use that function. 然后,我们简单地使用该功能。

 const keep = (eq) => (xs, ys) => xs.filter ( x => ys .some ( y => eq(x, y) ) ) const keepByPath = keep ( (x, y) => x.path == y.path ) const arr1 = [{ path: "path1", foo: 1 }, { path: "path2", foo: 2 }] const arr2 = [{ path: "path1", bar: 1 }] console.log ( keepByPath (arr1, arr2) //~> [{ path: "path1", foo: 1 }] ) 

Note that I added some properties. 请注意,我添加了一些属性。 These demonstrate that we keep only items from the first array. 这些证明我们只保留第一个数组中的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM