Using Lodash 4.17.11, how do you use groupBy
to group by value? Let me explain:
An array of objects:
{
a: 88,
b: 11,
},
{
a: 99,
b: 88
},
{
a: 22,
b: 10
}
Expected result:
88: [{
a: 88,
b: 11
},
{
a: 99,
b: 88
}]
Doing the below would be based on the actual key
._groupBy(array, (arr) => arr.a)
But I need to group by the actual value. Am I making sense? If b
is the same as a
in another object, then group it.
Im working with an old code base where things are not structured. Thanks.
You could do this in relatively concise manner with ES6 and Array.reduce
:
const group = arr => arr.reduce((r,{a,b}) => {
if(!r[a] && !r[b]) r[a] = r[b] = {a,b}
else {
if(r[a]) r.grp[a] = [...r.grp[a] || [r[a]], {a,b}]
if(r[b]) r.grp[b] = [...r.grp[b] || [r[b]], {a,b}]
}
return r
}, {grp: {}}).grp
console.log(group([{ a: 88, b: 11, }, { a: 99, b: 88 }, { a: 22, b: 10 }]))
console.log(group([{ a: 88, b: 11, }, { a: 99, b: 88 }, { a: 22, b: 10 }, { a: 22, b: 88 }]))
I would also argue that this should be considerably faster than doing 1 groupBy
on 'a'
, then another on 'b'
and then yet another loop to _.mergeBy
as with lodash
.
But if you want lodash you could do something like this:
const group = arr => {
return _.pickBy(
_.mergeWith(
_.groupBy(arr, 'a'),
_.groupBy(arr, 'b'),
(ov,sv,k,o,s) => o[k] && s[k] ? o[k].concat(s[k]) : false
),
x => _.isArray(x) && x.length > 1)
}
console.log(group([{ a: 88, b: 11, }, { a: 99, b: 88 }, { a: 22, b: 10 }]))
console.log(group([{ a: 88, b: 11, }, { a: 99, b: 88 }, { a: 22, b: 10 }, { a: 22, b: 88 }]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
Where you would group by each of the props then merge only those arrays where there is the same key
and then since the output is in arrays
just pickBy
the ones that have more than 1 item
in them.