Home > Enterprise >  How to group objects with the same value into a bigger object?
How to group objects with the same value into a bigger object?

Time:06-02

I have data in the following format:

data = [
 { group: G1, name: A},
 { group: G1, name: B},
 { group: G2, name: C},
 { group: G2, name: D}
]

and try to turn it into data in the format of:

 transformedData = [
  {group: G1, names: ['A','B']},
  {group: G2, names: ['C','D']}
]

I have no idea how to do it in JavaScript. Any help appreciated.

CodePudding user response:

Presented below is one possible way to achieve the desired objective.

Code Snippet

const myTransform = arr => (
  Object.values(
    arr.reduce(
      (acc, { group, name }) => (
        (
          acc[group] ??= ({
            group,
            names: []
          })
        ).names.push(name),
        acc
      ),
      {}
    )
  )
);

/* explanation
// method to transform array
const myTransform = arr => (
  Object.values(        // extract values from the result of below operation
    arr.reduce(         // iterate over "arr" using ".reduce()"
      (acc, { group, name }) => {     // "acc" is accumulator, destructure group, name
        // set-up key-value pair in "acc" for group with "names" array as part of value
        (acc[group] ??= ({ group, names: []}));
        // push the "name" into the "names" array
        acc[group].names.push(name);
        return acc;             // return "acc"
      },
      {}
    )
  )
);
*/

const data = [
 { group: 'G1', name: 'A'},
 { group: 'G1', name: 'B'},
 { group: 'G2', name: 'C'},
 { group: 'G2', name: 'D'}
];

console.log(
  'transformed array:\n',
  myTransform(data)
);
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Comments added to the snippet above.

CodePudding user response:

Be careful withe the declaration of data, otherwise you would get G1 not defined error.

Use Array#reduce and Object.values methods as follows:

const input = [{ group: "G1", name: "A"}, { group: "G1", name: "B"}, { group: "G2", name: "C"}, { group: "G2", name: "D"}],

      output = Object.values(
          input.reduce(
              (prev, {group,name}) =>
              prev[group] ? 
              ({...prev,[group]:{group,name:[...prev[group].name,name]}}) :
              ({...prev,[group]:{group,name:[name]}}), {}
          )
      );
      
console.log( output );

Alternatively ...

const input = [{ group: "G1", name: "A"}, { group: "G1", name: "B"}, { group: "G2", name: "C"}, { group: "G2", name: "D"}],

      output = input.reduce(
          (prev, {group,name}) => {
              const found = prev.find(item => item.group === group);
              if( found ) {
                  found.name.push( name );
              } else {
                  prev = [...prev, {group,name:[name]}];
              }
              return prev;
          }, []
      );
      
console.log( output );

  • Related