从嵌套对象数组中移除重复项

3
我有一个数组,其中包含另一个对象数组。我想删除这个二维数组中的重复项。
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}]
    }
]

由于在arr1中已经有一个名称相同且check: true的元素,因此我希望从第二个子数组中删除{name:"google",check:false}

以下是我尝试过的内容:

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/


4
请补充结果。您所说的“merge”是什么意思? 结果:(Please add the result as well.) “Merge”指合并或融合的意思。 - Nina Scholz
4
@FlashThunder 我们并不总能选择我们的数据。即使我们可以选择,也可能有更好的方式来询问同样的问题。 - Dave Newton
1
从arr2中删除{name: "google", check: false},因为它已经在arr1中了,然后合并arr1和arr2。 - Thalapathy
@NinaScholz:我已经更新了最终的输出... 谢谢 - Thalapathy
1
根据更新后我所看到的,您似乎想要使用arr2中即将出现的新数据来更新arr1的数据。这是您真正想要的吗? - Shidersz
@Shidersz:是的...那正是我在寻找的。 - Thalapathy
2个回答

3
你可以创建一组已检查过的名称,并递归过滤数组:

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));

为了将两个数组合并成一个(我猜这就是你所说的“merge”),你可以使用 .concat 函数将它们连接起来。

1
http://jsfiddle.net/t1zkLq53/1/ 看起来 flatMap 不可用... 我需要包含类似 rxjs 的任何软件包吗? - Thalapathy
1
@thalapathy 它是ESnext,一些浏览器可能仍不支持它,但在这种情况下它只是语法糖。for(const el of arr1) for(const child of el.child) 在这里也可以起作用。 - Jonas Wilms

2
理解您想要根据来自arr2的新数据更新arr1中元素的check属性,可能的一种方法是首先创建一个哈希表,将新的name和check值对应起来。对于这部分,我们使用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 上的值,而不会在其中插入任何新元素。

谢谢,但输出是包含另一个对象数组的数组...而不是对象数组...像下面这样...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}] } ] - Thalapathy
@Thalapathy,抱歉,我错过了那部分内容,我刚刚更新以考虑它。 - Shidersz

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