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