1

I have an array of data. Some of the key in the array are same. I would like to create a new array based on the key and add the other data.

This is my array

 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"                           
      }
    ];

I would like to convert the array in to the below format.

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" },                          
          ]
       }
      ];

I am working on a node environment.

1
  • Please show us what you've tried already. We'll happily help you work out the kinks with your solutions, but SO is not a free coding service. Commented May 15, 2018 at 4:12

3 Answers 3

3

You can create an object using Array#reduce first which maps name with items, and then create the final array by looping over the intermediate map using a for...of loop:

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

Sign up to request clarification or add additional context in comments.

Comments

0

Array.reduce is at rescue.This method accepts an accumulator and current item. Check in the accumulator if there exist an object where the value of name property is John or 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)

Comments

0

Use .reduce to group by name, and use .find inside the reducer to find if the matching name has already been added:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.