从一个数组中提取项目并添加到现有数组Javascript

时间:2016-09-26 18:23:45

标签: javascript arrays sorting

我有现有数组,并希望为ID匹配的每个项目添加另一个对象数组。

var existingData = [
    {
        "id": "0100",
        "name": "name 1",
        "message": [
            "Lorem blah blah 1",
            "Lorem blah blah 1.1"
        ]
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": [
            "Lorem blah blah 2",
            "Lorem blah blah 2.1",
            "Lorem blah blah 2.2"
        ]
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": [
            "Lorem blah blah 3",
            "Lorem blah blah 3.1",
            "Lorem blah blah 3.2",
            "Lorem blah blah 3.3",
            "Lorem blah blah 3.4"
        ]
    }
];

以下数组是我的第二个数组,其中“relatedId”与existingArray中的ID相同:

var data2 = [
  {"CandidateName": "Mary", "relatedId": ["0100", "0200"]},
  { "CandidateName": "John", "relatedId": ["0200"]},
  { "CandidateName":"Peter", "relatedId": ["0300", "0100"]},
  { "CandidateName": "Paul", "relatedId": ["0300"]}
];

如果ID匹配,我想从data2中提取“CandidateName”并将其放入existingData。

此特定问题已从此处延伸=> Group Javascript array of objects by ID

我已经尝试过了,但是浏览器挂起时我并没有走得太远:

var result = data.reduce(function(r, el) {

  // THIS INNER LOOP MAKES THE BROWSER HANG!!!
  data2.forEach(function (a){
    console.log('a',a); 
  });

  var e = el.id.slice(0, 2);
  if (!o[e]) {
    o[e] = {
      id: el.id,
      name: el.name,
      message: []
    }
    r.push(o[e]);
  }
  o[e].message.push(el.message);
  return r;
}, [])

所以我想结束这样的事情:

var existingData = [
    {
        "id": "0100",
        "name": "name 1",
        "message": [
            "Lorem blah blah 1",
            "Lorem blah blah 1.1"
        ],
        "CandidateName": ["Mary", "Peter"]
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": [
            "Lorem blah blah 2",
            "Lorem blah blah 2.1",
            "Lorem blah blah 2.2"
        ],
        "CandidateName": ["Mary", "John"]
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": [
            "Lorem blah blah 3",
            "Lorem blah blah 3.1",
            "Lorem blah blah 3.2",
            "Lorem blah blah 3.3",
            "Lorem blah blah 3.4"
        ],
        "CandidateName": ["Peter", "Paul"]
    }
]

4 个答案:

答案 0 :(得分:3)

data2创建哈希映射效率更高,因此您只需迭代该数组一次。密钥将是id&#39>

然后在迭代existingData时,这是一个简单的合并

var candidatesById = data2.reduce(function(a, c){
   c.relatedId.forEach(function(id){
       a[id] = a[id] || [];
       a[id].push(c.CandidateName);           
   });
   return a;
},{});

existingData.forEach(function(item){
    item.CandidateName = candidatesById[item.id] || [];// empty array if no match
})

答案 1 :(得分:2)

试试这个!概念是,使用初始数据,循环并搜索ID,添加适用的数据。

请注意,这不是一个特别有效的解决方案。



var existingData = [{
  "id": "0100",
  "name": "name 1",
  "message": [
    "Lorem blah blah 1",
    "Lorem blah blah 1.1"
  ]
}, {
  "id": "0200",
  "name": "name 2",
  "message": [
    "Lorem blah blah 2",
    "Lorem blah blah 2.1",
    "Lorem blah blah 2.2"
  ]
}, {
  "id": "0300",
  "name": "name 3",
  "message": [
    "Lorem blah blah 3",
    "Lorem blah blah 3.1",
    "Lorem blah blah 3.2",
    "Lorem blah blah 3.3",
    "Lorem blah blah 3.4"
  ]
}];

var toCombine = [{
  "CandidateName": "Mary",
  "relatedId": ["0100", "0200"]
}, {
  "CandidateName": "John",
  "relatedId": ["0200"]
}, {
  "CandidateName": "Peter",
  "relatedId": ["0300", "0100"]
}, {
  "CandidateName": "Paul",
  "relatedId": ["0300"]
}];

function merge() {
  existingData.forEach(function(initialItem) {
    toCombine.forEach(function(referenceItem) {
      if (referenceItem.relatedId.indexOf(initialItem.id) >= 0) {
        if (!Array.isArray(initialItem.CandidateName)) {
          initialItem.CandidateName = [];
        }
        initialItem.CandidateName.push(referenceItem.CandidateName);
      }
    });
  });
  console.log(existingData);
}

merge();




答案 2 :(得分:1)

这是另一个ES6解决方案:

data2.forEach( function (obj) {
    obj.relatedId.forEach( id => this.get(id).candidateName.push(obj.CandidateName));
}, new Map(existingData.map (
    obj => [obj.id, Object.assign(obj, { 'candidateName': [] } )] 
)));

var existingData = [
    {
        "id": "0100",
        "name": "name 1",
        "message": [
            "Lorem blah blah 1",
            "Lorem blah blah 1.1"
        ]
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": [
            "Lorem blah blah 2",
            "Lorem blah blah 2.1",
            "Lorem blah blah 2.2"
        ]
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": [
            "Lorem blah blah 3",
            "Lorem blah blah 3.1",
            "Lorem blah blah 3.2",
            "Lorem blah blah 3.3",
            "Lorem blah blah 3.4"
        ]
    }
];

var data2 = [
  {"CandidateName": "Mary", "relatedId": ["0100", "0200"]},
  { "CandidateName": "John", "relatedId": ["0200"]},
  { "CandidateName":"Peter", "relatedId": ["0300", "0100"]},
  { "CandidateName": "Paul", "relatedId": ["0300"]}
];

data2.forEach( function (obj) {
    obj.relatedId.forEach( id => this.get(id).candidateName.push(obj.CandidateName));
}, new Map(existingData.map (
    obj => [obj.id, Object.assign(obj, { 'candidateName': [] } )] 
)));

console.log(existingData);

这会将 existingData 转换为地图,由 id 键入,同时将 candidateName 数组(空)添加到对象中。

此映射作为第二个参数传递给forEach,从而将其定义为this对象。

data2 元素的forEach内,迭代 relatedId 值,并为每个 id 值对应< em> existingData 对象的 candidateName 数组使用 CandidateName 扩展。

答案 3 :(得分:1)

也许我们可以在ES6中做这样的事情;嗯..我从data2创建一个哈希表,并将其用作this中的map对象。

&#13;
&#13;
var existingData = [
    {
        "id": "0100",
        "name": "name 1",
        "message": [
            "Lorem blah blah 1",
            "Lorem blah blah 1.1"
        ]
    },
    {
        "id": "0200",
        "name": "name 2",
        "message": [
            "Lorem blah blah 2",
            "Lorem blah blah 2.1",
            "Lorem blah blah 2.2"
        ]
    },
    {
        "id": "0300",
        "name": "name 3",
        "message": [
            "Lorem blah blah 3",
            "Lorem blah blah 3.1",
            "Lorem blah blah 3.2",
            "Lorem blah blah 3.3",
            "Lorem blah blah 3.4"
        ]
    }
],
 data2 = [
  {"CandidateName": "Mary", "relatedId": ["0100", "0200"]},
  { "CandidateName": "John", "relatedId": ["0200"]},
  { "CandidateName":"Peter", "relatedId": ["0300", "0100"]},
  { "CandidateName": "Paul", "relatedId": ["0300"]}
],

newExistingData = existingData.map(function(o){
                                     o.CandidateName = this[o.id];
                                     return o;
                                   }, data2.reduce((h,o) => (o.relatedId.reduce((p,c) => (p[c] ? p[c].push(o.CandidateName)
	                                                                                       : p[c] = [o.CandidateName],p),h),h),{}));
console.log(newExistingData);
&#13;
&#13;
&#13;