Reputation: 329
I need to group the data by sub categories, but the property is an array.
I'll appreciate your help, if there is any way to do it with lodash or pure js.
const data = [
{
title: "data 1",
sub_categories:[{ id: 1, name: 'gold'},{ id: 2, name: 'water' }]
},
{
title: "data 2",
sub_categories:[{ id: 2, name: 'water'}]
},
{
title: "data 3",
sub_categories:[{ id: 1, name: 'gold'},{ id: 3, name: 'fire' }]
},
{
title: "data 4",
sub_categories:[] // also can be empty
}
]
_.chain(data)
.groupBy(props => ) //need help here
.map(({values, key}) => {
return {
values,
key
}
})
.value();
[
{
subcategory: "gold",
list: [{title: "data 1"}, {title: "data: 3"}]
}
]
Upvotes: 0
Views: 520
Reputation: 386883
You could group by nested values.
const
data = [{ title: "data 1", sub_categories: [{ id: 1, name: 'gold' }, { id: 2, name: 'water' }] }, { title: "data 2", sub_categories: [{ id: 2, name: 'water' }] }, { title: "data 3", sub_categories: [{ id: 1, name: 'gold' }, { id: 3, name: 'fire' }] }, { title: "data 4", sub_categories: [] }],
result = Object.values(data.reduce((r, { title, sub_categories }) => {
sub_categories.forEach(({ name: subcategory }) => (r[subcategory] ??= { subcategory, list: []}).list.push({ title }));
return r;
}, {}));
console.log(result) ;
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 1202
var _ = require('lodash');
const data = [
{
title: "data 1",
sub_categories:[{ id: 1, name: 'gold'},{ id: 2, name: 'water' }]
},
{
title: "data 2",
sub_categories:[{ id: 2, name: 'water'}]
},
{
title: "data 3",
sub_categories:[{ id: 1, name: 'gold'},{ id: 3, name: 'fire' }]
},
{
title: "data 4",
sub_categories:[] // also can be empty
}
]
g= _.groupBy(data.map(d=>d.sub_categories.map(s=>({"title":d.title, "name":s.name }))).flat(),"name")
ans=[]
for (const key in g){
ans.push({"subcategory":key,"list": g[key].map(v=>({"title":v.title}))})
}
console.log(
ans
)
You can use above code to get the expected results. groupBy using loadash and other operations done using inbuild functions.
Upvotes: 1
Reputation: 50974
You could do this in a couple of steps, which you can combine together with _.flow()
:
sub_categories
. This way we 'expand' the array to now include a data
object for each subcatgory.name
of the subcategory_.map()
const data = [ { title: "data 1", sub_categories:[{ id: 1, name: 'gold'},{ id: 2, name: 'water' }] }, { title: "data 2", sub_categories:[{ id: 2, name: 'water'}] }, { title: "data 3", sub_categories:[{ id: 1, name: 'gold'},{ id: 3, name: 'fire' }] }, { title: "data 4", sub_categories:[] /* also can be empty */} ];
const grp = _.flow(
arr => _.flatMap(arr, obj => _.map(obj.sub_categories, ({name}) => ({...obj, name}))),
flattened => _.groupBy(flattened, 'name'),
grpd => _.map(grpd, (arr, subcategory) => ({subcategory, list: _.map(arr, ({title}) => ({title}))}))
);
console.log(grp(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Upvotes: 1