好的,这是按ID分组Javascript对象数组系列中的另一个,但是这一次,我们在数组对象(item3(中有一个ID数组,它将与另一个对象数组进行比较。
var existingArray = [
{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200","0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100","0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200", "0100"],
"item4": "blah4",
"item5": "blah5"
}
]
这是我们最喜欢的 DATA2 数组,它包含我们想要提取的信息(Candidate Name(,如果"relatedId"与 EXISTINGARRAY 中 item3 中的任何 ID 相同。
var data2 = [
{"CandidateName": "Mary", "relatedId": ["0100", "0200"]},
{ "CandidateName": "John", "relatedId": ["0200"]},
{ "CandidateName":"Peter", "relatedId": ["0300", "0100"]},
{ "CandidateName": "Paul", "relatedId": ["0300"]}
];
所以这个想法是,如果data2[i].relatedId[j] === existingArray[k].item3[l]中的任何ID,提取"Candidate Name"并将其添加到EXISTINGARRAY中,这样我们最终会得到如下所示的内容。
existingArray = [
{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200","0300"],
"item4": "blah4",
"item5": "blah5",
"item6": ["Mary", "Jonh", "Peter", "Paul"]
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100","0300"],
"item4": "blah4",
"item5": "blah5",
"item6": ["Mary", "Peter", "Paul"]
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100"],
"item4": "blah4",
"item5": "blah5",
"item6": ["Mary", "Peter"]
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0300"],
"item4": "blah4",
"item5": "blah5",
"item6": ["Peter", "Paul"]
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200", "0100"],
"item4": "blah4",
"item5": "blah5",
"item6": ["Mary", "John","Peter"]
}
]
下面是一个 ES6 解决方案:
existingArray.forEach( function (obj) {
obj.item6 = [...new Set(obj.item3.reduce( (acc, id) => acc.concat(this.get(id)), [] ))]
}, data2.reduce (
(acc, obj) => obj.relatedId.reduce (
(acc, id) => acc.set(id, (acc.get(id) || []).concat(obj.CandidateName)), acc
), new Map()
));
var existingArray = [
{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200","0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100","0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0100"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0300"],
"item4": "blah4",
"item5": "blah5"
},{
"item1": "Blah1",
"item2": "blah2",
"item3": ["0200", "0100"],
"item4": "blah4",
"item5": "blah5"
}
]
var data2 = [
{"CandidateName": "Mary", "relatedId": ["0100", "0200"]},
{ "CandidateName": "John", "relatedId": ["0200"]},
{ "CandidateName":"Peter", "relatedId": ["0300", "0100"]},
{ "CandidateName": "Paul", "relatedId": ["0300"]}
];
existingArray.forEach( function (obj) {
obj.item6 = [...new Set(obj.item3.reduce( (acc, id) => acc.concat(this.get(id)), [] ))]
}, data2.reduce (
(acc, obj) => obj.relatedId.reduce (
(acc, id) => acc.set(id, (acc.get(id) || []).concat(obj.CandidateName)), acc
), new Map()
));
console.log(existingArray);
解释
代码真正从最后开始,创建一个空Map
:
new Map()
这成为变量(名为 acc
(,当 data2
迭代时reduce
累积数据:
data2.reduce
此reduce
操作是嵌套的,以便单独迭代每个relatedId
。如果累积值 ( acc
( 尚未包含找到的 id,则创建一个新数组:
acc.get(id) || []
。否则,将使用找到的数组值。将附加候选名称:
.concat(obj.CandidateName)
。这被放回acc
键id
:
acc.set(id, ...)
当 set
方法返回自身acc
时,它与需要此返回值以便再次acc
回调的下一次调用的reduce
配合得很好。
外部reduce
调用的结果是,这是一个由data2
中找到的所有id
值键控的Map
,每个值都是关联名称的数组。
然后,此值作为第二个参数传递给forEach
调用,从而成为 this
的值。所以当你看到:
this.get(id)
它正在从上述Map
中检索id
的候选名称数组。
在forEach
回调中,进行了另一个reduce
来迭代item3
中的id
值:
obj.item3.reduce
这会累积到一个名称数组中,然后将其传递给 Set
构造函数:
new Set(...)
这样做是为了从名称数组中删除重复项。此Set
立即使用扩展运算符再次转换为数组:
[...new Set()]
因此,所有item6
属性都获得了它们的价值。
您可以循环 existingArray 并使用 map()
添加 item6,要创建该数组,您可以首先使用 filter()
和 some()
来过滤 relatedId 中包含与现有数组中当前对象相同值的对象,然后仅使用 map()
仅返回名称和返回对象。
var existingArray = [{"item1":"Blah1","item2":"blah2","item3":["0200","0300"],"item4":"blah4","item5":"blah5"},{"item1":"Blah1","item2":"blah2","item3":["0100","0300"],"item4":"blah4","item5":"blah5"},{"item1":"Blah1","item2":"blah2","item3":["0100"],"item4":"blah4","item5":"blah5"},{"item1":"Blah1","item2":"blah2","item3":["0300"],"item4":"blah4","item5":"blah5"},{"item1":"Blah1","item2":"blah2","item3":["0200","0100"],"item4":"blah4","item5":"blah5"}];
var data2 = [{"CandidateName":"Mary","relatedId":["0100","0200"]},{"CandidateName":"John","relatedId":["0200"]},{"CandidateName":"Peter","relatedId":["0300","0100"]},{"CandidateName":"Paul","relatedId":["0300"]}];
var result = existingArray.map(function(o) {
o.item6 = data2.filter(function(e) {
return o.item3.some(function(a) {
return e.relatedId.indexOf(a) != -1;
})
}).map(function(e) {
return e.CandidateName;
})
return o;
})
console.log(result)