繁体   English   中英

从Array of Array(嵌套的对象数组)中删除重复项

[英]Remove duplicates from Array of Array (nested array of objects)

我有一个Array,它拥有另一个对象Array。 我想删除此数组数组中的重复项。

var arr1 = [{
     child: [{name: "google", check: false}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    },
    {
     child: [{name: "something1", check: false}, {name: "something2", check: false}]
    }
]

var arr2 = [{
     child: [{name: "google", check: true}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    } 
]

var arr3 = [{
     child: [{name: "google", check: true}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    },
    {
     child: [{name: "something1", check: false}, {name: "something2", check: false}]
    }
]

我想从第二个子数组中删除{name: "google", check: false} ,因为已经有一个具有相同名称并且在arr1 check: true

以下是我尝试过的东西。

function mergeAndRemoveDuplicates(arr1, arr2) {

    return arr1.map(function(child) {
        return child.some(function(children) {
            return arr2.map(function(child2) {
                return child2.some(function(children2) {
                    return children.name === children2.name &&
                        children.check === true;
                });
            })
        })
    })
}

console.log(mergeAndRemoveDuplicates(arr1, arr2));

http://jsfiddle.net/g7rvbpf3/

您可以创建一组已检查的名称并以递归方式过滤数组:

const dupes = new Set;

for(const el of arr1.concat(arr2))
  el.child = el.child.filter(el => {
     const dupe = dupes.has(el.name);
     if(el.check) dupes.add(el.name);
     return !dupe;
  });

这也将过滤arr1重复项,如果不需要,可以使用arr1来构建集合,并过滤arr2

 const dupes = new Set;

 for(const child of arr1.flatMap(it => it.child))
   if(child.checked) dupes.add(child.name);

for(const el of arr2)
 el.child = el.child.filter(it => !dupes.has(it.name));

要在最后得到一个数组(我想这就是你对“合并”的意思)你可以只将.concat转换为另一个。

了解您要根据arr2即将发布的新数据更新arr1元素的check属性,一种可能的方法是首先在新的即将到来的namecheck值之间创建一个哈希表。 对于这部分,我们使用Array.reduce() 该方法的第二部分由Array.map()构成,用于保存新更新的arr1的元素。

 var arr1 = [ { child: [{name: "google", check: false}, {name: "yahoo", check: false}] }, { child: [{name: "excite", check: false}, {name: "facebook", check: false}] }, { child: [{name: "something1", check: false}, {name: "something2", check: false}] } ]; var arr2 = [ { child: [{name: "google", check: true}, {name: "yahoo", check: false}] }, { child: [{name: "excite", check: false}, {name: "facebook", check: false}] } ]; let upHashTable = arr2.reduce((acc, {child}) => { child.forEach(({name, check}) => acc[name] = check); return acc; }, {}); console.log("HashTable with updates: ", upHashTable); let updated = arr1.map(({child}) => { return {child: child.map(o => { o.check = upHashTable.hasOwnProperty(o.name) ? upHashTable[o.name] : o.check; return o; })}; }); console.log("Updated arr1 is: ", updated); 
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;} 

请注意,这只会更新arr1值,并且不会在其上插入任何新元素。

暂无
暂无

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

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