Reputation: 31
I am trying to restructure an array. Instead of variant_id at the top, i would like to make collection_id to the top. if the collection_id is the same they should be in the same array. I try using foreach but seems didn't work.
[
{
variant_id: '39264031277264',
collection: [
{
collection_id: '260687954128',
value: true
}
]
},
{
variant_id: '39264022134992',
collection: [
{
collection_id: '260687954128',
value: true
}
]
},
{
variant_id: '40460795642064',
collection: [
{
collection_id: '277033681104',
value: true
}
]
}
]
This is the expected result
[
{
"collection_id":"260687954128",
"variant_id":[
"39264031277264",
"39264022134992"
]
},
{
"collection_id":"277033681104",
"variant_id":[
"40460795642064"
]
}
]
Upvotes: 1
Views: 80
Reputation: 3691
The below solution may be one possible way to achieve the desired objective.
It uses the following JavaScript concepts/features/ideas:
Object.values
Array.reduce()
...
spread operator?.
optional chaining operator??
nullish coalescing operatorCode Snippet
const reGroupUsingCollectionId = arr => (
Object.values( // extract only the 'values' of resulting object
arr.reduce( // use .reduce() to iterate the array
(acc, itm) => ( // 'acc' is the accumulator & 'itm' is current element
itm.collection.reduce( // use .reduce() to iterate over 'collection' array
(fin, {collection_id}) => ({ // 'fin' is the inner-reduce's accumulator
...fin, // collection_id is de-structured from iterator
[collection_id]: {
collection_id,
variant_id: [ // populate the variant_id array
...( //
fin[collection_id] // use existing variant_id array if collection_id
?.variant_id // already added to accumulator (fin)
?? [] // nullish coalescing as empty
),
itm.variant_id // append itm.variant_id to variant_id array
]
}
}),
{...acc} // initialize 'fin' to be 'acc'
)
),
{} // initialize 'acc' to be empty object
)
)
);
const data = [{
variant_id: '39264031277264',
collection: [{
collection_id: '260687954128',
value: true
}]
}, {
variant_id: '39264022134992',
collection: [{
collection_id: '260687954128',
value: true
}]
}, {
variant_id: '40460795642064',
collection: [{
collection_id: '277033681104',
value: true
}]
}
];
console.log(reGroupUsingCollectionId(data));
Explanation
Inline comments provide detailed description of each significant step.
Upvotes: 0
Reputation: 24565
You can define a simple mapping function that collects all collection_id
s and keeps track of the respective variant_id
s:
const data = [{
variant_id: '39264031277264',
collection: [{collection_id: '260687954128', value: true}]
}, {
variant_id: '39264022134992',
collection: [{collection_id: '260687954128', value: true}]
}, {variant_id: '40460795642064', collection: [{collection_id: '277033681104', value: true}]}
];
function mapData(input) {
const collections = {};
for (const variant of input) {
for (const collection of variant.collection) {
collections[collection.collection_id] = collections[collection.collection_id] ?? [];
collections[collection.collection_id].push(variant.variant_id);
}
}
return Object
.entries(collections)
.map(([key, value]) => ({collection_id: key, variant_id: value}));
}
console.log(mapData(data));
Upvotes: 2