minsuga
minsuga

Reputation: 341

How to create array of object from nested array?

I have the following array:

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

I need to convert in the following format:

const a = [{
      Type: 'student',
      Names: [{
          Firstname: 'martha',
          Lastname: 'james'
        },
        {
          Firstname: 'Julie',
          Lastname: 'schrutt'
        }
      ],
    },
    {
      Type: 'Teacher',
      Names: [{
        Firstname: 'meredith',
        Lastname: 'Napier'
      }, ],
    }

I have tried lodash grouping, object.entries, array map, reduce, but not able to figure out how to do it.

Upvotes: 0

Views: 117

Answers (7)

Nithish
Nithish

Reputation: 5999

We can use Array.reduce & Object.values in order to achieve the expected output.

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] = acc[key] || { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper {
  max-height: 100% !important;
}

We can also use Logical nullish assignment (??=) instead of acc[obj[by]] = acc[obj[by]] || { Type, Names: []}

const a = [{Name:'martha',Surname:'james',Type:'student'},{Name:'Meredith',Surname:'Napier',Type:'Teacher'},{Name:'Julie',Surname:'Schrutt',Type:'student'}];

const groupBy = (data, by) => {
  const result = data.reduce((acc, obj) => {
    const key = obj[by];
    const { Type, Name: Firstname, Surname: Lastname } = obj;
    acc[key] ??= { Type, Names: []};
    acc[key].Names.push({ Firstname, Lastname });
    return acc;
  }, {});
  return Object.values(result);
}

console.log(groupBy(a, "Type"));
.as-console-wrapper { 
  max-height: 100% !important;
}

Upvotes: 0

use this method for any group by :

const groupBy = function (list, key) {
  return list.reduce((finalList, item) => {
    const group = (finalList[item[key]] = finalList[item[key]] || [])
    group.push(item)
    return finalList
  }, {})
}

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

console.log(groupBy(a, 'Type'))

Upvotes: 1

Gopi krishna
Gopi krishna

Reputation: 355

const data = [{
        Name: 'martha',
        Surname: 'james',
        Type: 'student',
    },
    {
        Name: 'Meredith',
        Surname: 'Napier',
        Type: 'Teacher',
    },
    {
        Name: 'Julie',
        Surname: 'Schrutt',
        Type: 'student',
    }
]

function processData(data) {
    finalMap = new Map();
    data.forEach((obj) => {
        let typeName = obj["Type"];
        let firstName = obj["Name"];
        let lastName = obj["Surname"];
        if (!finalMap[typeName]) {
            finalMap[typeName] = [];
        }
        finalMap[typeName].push({
            "Firstname": firstName,
            "LastName": lastName
        });
    });
    let result = [];
    for (const [key, value] of Object.entries(finalMap)) {
        result.push({
            "Type": key,
            "Names": value
        });
    }
    return result;

}
console.log(processData(data));

Upvotes: 0

Nikita Mazur
Nikita Mazur

Reputation: 1785

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
]

const types = a.reduce((acc, next) => {
    if (acc.includes(next.Type)) {
    return acc
  }
  return acc.concat(next.Type)
}, [])

const arrayByTypes = types.map((type) => {
    return {
    Type: type,
    Names: a.filter(item => item.Type === type).map(filtered => ({ Name: filtered.Name, Surname: filtered.Surname }))
    }
})

console.log(arrayByTypes)

Upvotes: 0

Carlo Moretti
Carlo Moretti

Reputation: 2250

Try something like this:

const output = {};    

for(const person of array) {
    if(!output[person.Type]) output[person.Type] = { Type: person.Type, Names:[] };
    output[person.Type].Names.push({ Firstname: person.Name, Lastname: person.Surname });
}

return Object.values(output);

Or in short:

Object.values(array.reduce((pre, curr) => {
    if(!pre[curr.Type]) pre[curr.Type] = { Type: curr.Type, Names:[] };
    pre[curr.Type].Names.push({ Firstname: curr.Name, Lastname: curr.Surname });
    return pre;
} , {}))

Upvotes: 0

LaytonGB
LaytonGB

Reputation: 1404

Using forEach:

const a = [{
    Name: 'martha',
    Surname: 'james',
    Type: 'student',
  },
  {
    Name: 'Meredith',
    Surname: 'Napier',
    Type: 'Teacher',
  },
  {
    Name: 'Julie',
    Surname: 'Schrutt',
    Type: 'student',
  }
];

const out = [{Type: 'student', Names: []}, {Type: 'teacher', Names: []}];
a.forEach(a => {
  if (a.Type === 'student')
    return out[0].Names.push({
        Firstname: a.Name,
        Lastname: a.Surname,
    });
  out[1].Names.push({
      Firstname: a.Name,
      Lastname: a.Surname,
  });
});

console.log(out);

Upvotes: 0

DecPK
DecPK

Reputation: 25408

You can easily achieve this result using reduce in js.

const a = [
  {
    Name: "martha",
    Surname: "james",
    Type: "student",
  },
  {
    Name: "Meredith",
    Surname: "Napier",
    Type: "Teacher",
  },
  {
    Name: "Julie",
    Surname: "Schrutt",
    Type: "student",
  },
];

const result = a.reduce((acc, curr) => {
  const { Name, Surname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({
      Firstname: Name,
      Lastname: Surname,
    });
  } else {
    acc.push({
      Type,
      Names: [
        {
          Firstname: Name,
          Lastname: Surname,
        },
      ],
    });
  }
  return acc;
}, []);

console.log(result);

You can make the above code snippet shorter if you change the name of the variable while destructuring

const { Name: Firstname, Surname: Lastname, Type } = curr;

and use it as

elSearch.Names.push({ Firstname, Lastname });

const a = [
  { Name: "martha", Surname: "james", Type: "student"},
  { Name: "Meredith", Surname: "Napier", Type: "Teacher"},
  { Name: "Julie", Surname: "Schrutt", Type: "student"},
];

const result = a.reduce((acc, curr) => {
  const { Name: Firstname, Surname: Lastname, Type } = curr;
  const elSearch = acc.find((o) => o.Type === Type);
  if (elSearch) {
    elSearch.Names.push({ Firstname, Lastname });
  } else {
    acc.push({ Type, Names: [{ Firstname, Lastname }] });
  }

  return acc;
}, []);

console.log(result);

Upvotes: 4

Related Questions