如果某些键使用JavaScript相同,则从另一个数组构建数组

时间:2018-05-15 04:10:51

标签: javascript

我有一组数据。数组中的一些键是相同的。我想基于密钥创建一个新数组并添加其他数据。

这是我的数组

 var myObjOne = [
        {
        "name":"John",
        "id":1,
        "car":"maruti"
       },
       {
        "name":"John",
        "id":2,
        "car":"wolks"
       },
       {
        "name":"John",
        "id":3,
        "car":"bmw"
       },        
      {
        "name":"Peter",       
        "id":4, 
        "car":"alto"                           
      },
      {
        "name":"Peter",       
        "id":5, 
        "car":"swift"                           
      }
    ];

我想将数组转换为以下格式。

var myObj = [
          {
          "name":"John",
          "items": [
              { "id":1, "car":"maruti" },  
              { "id":2, "car":"wolks" },
              { "id":3, "car":"bmw" }            
          ]},
          {
            "name":"Peter",
          "items": [
              { "id":4, "car":"alto" },  
              { "id":5, "car":"swift" },                          
          ]
       }
      ];

我正在开发一个节点环境。

3 个答案:

答案 0 :(得分:3)

您可以首先使用Array#reduce创建一个对象,将名称与项目映射,然后通过使用for...of循环遍历中间地图来创建最终数组:

var source = [{"name":"John","id":1,"car":"maruti"},{"name":"John","id":2,"car":"wolks"},{"name":"John","id":3,"car":"bmw"},{"name":"Peter","id":4,"cars":"alto"},{"name":"Peter","id":5,"cars":"swift"}];

const map = source.reduce((acc, {name, ...obj}) => {
  if (!acc[name]) {
    acc[name] = [];
  }
  
  acc[name].push(obj);
  return acc;
}, {});

const result = [];

for (let[name, items] of Object.entries(map)) {
  result.push({name, items});
}

console.log(result);

答案 1 :(得分:0)

使用.reduce按名称分组,并使用缩减器内的.find查找是否已添加匹配的name

const input=[{"name":"John","id":1,"car":"maruti"},{"name":"John","id":2,"car":"wolks"},{"name":"John","id":3,"car":"bmw"},{"name":"Peter","id":4,"cars":"alto"},{"name":"Peter","id":5,"cars":"swift"}]
const output = input.reduce((a, { name, ...item }) => {
  const foundNameObj = a.find(nameObj => nameObj.name === name);
  if (foundNameObj) foundNameObj.items.push(item);
  else a.push({ name, items: [item] });
  return a;
}, []);
console.log(output);

答案 2 :(得分:0)

Array.reduce正在救援。这个方法接受accumulatorcurrent 项目。检查累加器是否存在name属性值为John或Peter

的对象

var myObjOne = [{
    "name": "John",
    "id": 1,
    "car": "maruti"
  },
  {
    "name": "John",
    "id": 2,
    "car": "wolks"
  },
  {
    "name": "John",
    "id": 3,
    "car": "bmw"
  },
  {
    "name": "Peter",
    "id": 4,
    "car": "alto"
  },
  {
    "name": "Peter",
    "id": 5,
    "car": "swift"
  }
];

var newObj = myObjOne.reduce(function(acc, curr, currIndex) {
  // using findIndex to check if there exist an object
  // where the value of the name property is John, Peter
  // if it exist it will return the index else it will return -1
  let ifNameExist = acc.findIndex(function(item) {
    return item.name === curr.name;
  })
  // if -1 then create a object with name and item property and push
  // it to the accumulator
  if (ifNameExist === -1) {
    let nameObj = {};
    nameObj.name = curr.name;  
    nameObj.items = [];
    nameObj.items.push({
      id: curr.id,
      car: curr.car
    })
    acc.push(nameObj)
  } else {
    // if such an object already exist then just update the item array
    acc[ifNameExist].items.push({
      id: curr.id,
      car: curr.car
    })

  }


  return acc;

}, []);
console.log(newObj)