将二维数组中的ID与另一个二维数组

时间:2016-09-27 20:02:38

标签: javascript arrays multidimensional-array

好的,另一个是按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数组,其中包含我们想要提取的信息(CandidateName),如果“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,拉出“CandidateName”并将其添加到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"]
    }
]

2 个答案:

答案 0 :(得分:1)

以下是针对此的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,它与reduce非常吻合,需要此返回值才能再次将acc传递给下一次调用回调。

外部reduce调用的结果是Map,它由id中找到的所有data2值键入,每个值都是一个数组相关名称。

然后将此值作为第二个参数传递给forEach调用,从而成为this的值。所以当你看到:

this.get(id)

它正在从上述id中检索Map的候选名称数组。

forEach回调中,另一个reduce会迭代id中的item3值:

obj.item3.reduce

这会累积到一个名称数组,然后传递给Set构造函数:

new Set(...)

这样做是为了从名称数组中删除重复项。使用扩展运算符立即将此Set转换为数组:

[...new Set()]

因此所有item6属性都会获得它们的价值。

答案 1 :(得分:1)

您可以循环使用existingArray并使用map()添加item6,并且要创建该数组,您可以先使用filter()some()过滤在relatedId中包含与当前对象相同的值的对象。 existingArray然后只使用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)