I am looking to take an array of objects, and convert it into an array of subarrays based on a chosen object property
for example:
[
{foo: 1, bar: a}, {foo: 2, bar: b}, {foo: 1, bar: c}, {foo: 2, bar: d}
]
Create subarrays with the foo property would become:
[
[
{foo: 1, bar: a}, {foo: 1, bar: c},
],
[
{foo: 2, bar: b}, {foo: 2, bar: d}
]
]
I can't think of an efficient way to this. I keep resorting to creating a set of all of the unique property values of my chosen value, and then brute forcing through it multiple times.
const distinctProperties = [...new Set(originalArray.map(item => item.foo))]
const newArray = distinctProperties.map(item => originalArray.filter(obj => obj.foo === item))
Thanks in advance for some advice here!
CodePudding user response:
can be done with reduce
. you can wrap this around another function to group by the key you want.
Here I'm grouping based on the value of foo
and res
will be like this
{
1: [{
bar: "a",
foo: 1
}, {
bar: "c",
foo: 1
}],
2: [{
bar: "b",
foo: 2
}, {
bar: "d",
foo: 2
}]
}
then I'm taking Object.values
of this to get the array format you want
let a =[
{foo: 1, bar: 'a'}, {foo: 2, bar: 'b'}, {foo: 1, bar: 'c'}, {foo: 2, bar: 'd'}
]
let res= Object.values(a.reduce((acc,curr)=> {
if(!acc[curr.foo])acc[curr.foo]=[];
acc[curr.foo].push(curr)
return acc;
},{}))
console.log(res)
As a generalized function to take key name as input
let a =[
{foo: 1, bar: 'a'}, {foo: 2, bar: 'b'}, {foo: 1, bar: 'c'}, {foo: 2, bar: 'd'}
]
let groupByValue = (arr,key) => {
return Object.values(arr.reduce((acc,curr)=> {
if(!acc[curr[key]])acc[curr[key]]=[];
acc[curr[key]].push(curr)
return acc;
},{}))
}
let res1 = groupByValue(a,'foo')
let res2 = groupByValue(a,'bar')
console.log(res1)
console.log(res2)