Can we achieve a group by on an array of objects by object's key where key is also an array?
[
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
]
Wanted results in an object after the group by:
{
"fruits": [
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
],
"vegetables": [
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
]
}
Vanilla or Lodash solution is very wele!
Edit
Thanks everyone, here is what I ended up using:
const groupBy = key => array =>
array.reduce((obj, el) => {
el[key].forEach(k => {
obj[k] = obj[k] || []
obj[k].push({ ...el })
})
return obj
}, {})
const groupBySomething = groupBy(`something`)
const grouped = groupBySomething(data)
Can we achieve a group by on an array of objects by object's key where key is also an array?
[
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
]
Wanted results in an object after the group by:
{
"fruits": [
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
],
"vegetables": [
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
]
}
Vanilla or Lodash solution is very wele!
Edit
Thanks everyone, here is what I ended up using:
const groupBy = key => array =>
array.reduce((obj, el) => {
el[key].forEach(k => {
obj[k] = obj[k] || []
obj[k].push({ ...el })
})
return obj
}, {})
const groupBySomething = groupBy(`something`)
const grouped = groupBySomething(data)
Share
Improve this question
edited Nov 19, 2020 at 12:04
wassim
asked Nov 19, 2020 at 11:39
wassimwassim
391 silver badge8 bronze badges
2
- Have you tried anything ? – Gabriele Petrioli Commented Nov 19, 2020 at 11:43
- @GabrielePetrioli I tried with Lodash's _.groupBy couldn't get it working. – wassim Commented Nov 19, 2020 at 11:45
3 Answers
Reset to default 3This uses Array.prototype.reduce and Array.prototype.forEach
{
const data = [
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
]
const groupedData = data.reduce((carry, element) => {
element.tags.forEach(tag => {
carry[tag] = carry[tag] || []
carry[tag].push({...element})
})
return carry;
}, {})
console.log(groupedData)
}
Here:
let arr = [
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
];
let response = {};
for(let i of arr){
for(let j of i.tags){
let tags =[...i.tags]
if(response[j]){
response[j].push({...i , tags: tags})
} else{
response[j] = [{...i, tags: tags}];
}
}
}
console.log(response)
A slightly more terse version of @yunzen version.
input data:
const data = [
{
"name": "Apple",
"tags": ["fruits"]
},
{
"name": "Orange",
"tags": ["fruits"]
},
{
"name": "Tomato",
"tags": ["fruits", "vegetables"]
}
];
const convertData = data.reduce((target, currentElem) => {
currentElem.tags.forEach(tag => {
target[tag] ? target[tag].push({...currentElem}) : target[tag] = [{...currentElem}];
});
return target;
}, {});
console.log(convertData);