0

I have a array like this:

[
  {name: "A", age: 20, username: "a1"},
  {name: "B", age: 21, username: "b1"},
  {name: "A", age: 22, username: "a2"},
  {name: "B", age: 25, username: "b2"},
]

How can I convert it to this:

[
  {name: "A", props: [{age: 20, username: "a1"}, {age: 22, username: "a2"}]},
  {name: "B", props: [{age: 21, username: "b1"}, {age: 25, username: "b2"}]}
]
Amin Azimi
  • 659
  • 9
  • 25
  • I don't think es6 has a feature for that. But if you're interested in lodash solution, [this answer](https://stackoverflow.com/a/23600960/863110) is very similar to what you need. https://jsbin.com/nekiyus/edit?html,js,console – Mosh Feu Sep 13 '20 at 10:07

3 Answers3

3

You could make a Map, keyed by the names, and where the corresponding value is an object with an empty props array. Then iterate the data to populate those props arrays, and finally extract those objects from the map:

let data = [{name: "A", age: 20, username: "a1"},{name: "B", age: 21, username: "b1"},{name: "A", age: 22, username: "a2"},{name: "B", age: 25, username: "b2"}];

let map = new Map(data.map(({name}) => [name, { name, props: [] }]));
for (let { name, ...rest } of data) map.get(name).props.push(rest);
let result = [...map.values()];

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286
2

This will give you the desired result

names = [
  {name: "A", age: 20, username: "a1"},
  {name: "B", age: 21, username: "b1"},
  {name: "A", age: 22, username: "a2"},
  {name: "B", age: 25, username: "b2"},
]
var namesGrp = [];
for(var nameD of names) {
    var i = namesGrp.findIndex(nameG => nameG.name == nameD.name);
    if(i == -1) {
        var newName = {
            name: nameD.name,
            props: []
        };
        namesGrp.push(newName);
        i = namesGrp.length -1;
    }
    delete nameD.name;
    namesGrp[i].props.push(nameD);
}
console.log(namesGrp);
aRvi
  • 2,203
  • 1
  • 14
  • 30
0

var users=[
  {name: "A", age: 20, username: "a1"},
  {name: "B", age: 21, username: "b1"},
  {name: "A", age: 22, username: "a2"},
  {name: "B", age: 25, username: "b2"},
];

var result=
  Object.entries(
    users.map(item=>[item.name, item.age, item.username])
    .reduce((acc,cv)=>{
      if(acc[cv[0]]==undefined)
        acc[cv[0]]={name:cv[0], props:[]};
      acc[cv[0]].props.push({age:cv[1], username:cv[2]});
      return acc;
    },{})
  )
  .reduce((acc,cv)=>{
    acc.push(cv[1]);
    return acc;
  },[])
;

console.log(result);

Map users Array to an Array of Array of values.
Reduce that into an object with name as 1st item, create if not yet exists with props Array, and push 2nd and 3rd items = age and username - into props.
Transform this object's entries into an array, and push each object into an Array.

For users with more or less or different properties, code will need to be adjusted.
Perhaps I'll edit sometime for general use, say: function joinArrayBy(prop).

iAmOren
  • 2,760
  • 2
  • 11
  • 23