lodash - group and populate arrays
You can use reduce()
and find()
let arr = [{
"birthdate": "1993",
"name": "Ben"
},
{
"birthdate": "1994",
"name": "John"
},
{
"birthdate": "1995",
"name": "Larry"
},
{
"birthdate": "1995",
"name": "Nicole"
},
{
"birthdate": "1996",
"name": "Jane"
},
{
"birthdate": "1996",
"name": "Janet"
},
{
"birthdate": "1996",
"name": "Dora"
},
];
const res = arr.reduce((ac, a) => {
let temp = ac.find(x => x.birthdate === a.birthdate);
if (!temp) ac.push({ ...a,
name: [a.name]
})
else temp.name.push(a.name)
return ac;
}, [])
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
You can chain groupBy and map to achieve this.
_.chain(yourArray)
.groupBy('birthdate')
.toPairs()
.map(s=>{
return _.zipObject(['birthdate','names'],s)
})
.map(s=>{
s.names=_.map(s.names,x=>x.name);
return s;
})
.value()
You can use groupBy() to group each item in the collection by birthdate
. After grouping the items, you can use map() to iterate each groups and form them into a new format that includes a birthdate
and names
. To acquire an array of names from the grouped items, you can use the map() function again to return all the name
values.
var result = _(source)
.groupBy('birthdate')
.map(function(items, bdate) {
return {
birthdate: bdate,
names: _.map(items, 'name')
};
}).value();
var source = [
{ "birthdate": "1993", "name": "Ben" },
{ "birthdate": "1994", "name": "John" },
{ "birthdate": "1995", "name": "Larry" },
{ "birthdate": "1995", "name": "Nicole" },
{ "birthdate": "1996", "name": "Jane" },
{ "birthdate": "1996", "name": "Janet" },
{ "birthdate": "1996", "name": "Dora" },
];
var result = _(source)
.groupBy('birthdate')
.map(function(items, bdate) {
return {
birthdate: bdate,
names: _.map(items, 'name')
};
}).value();
document.body.innerHTML = '<pre>' + JSON.stringify(result, 0, 4) + '</pre>';
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
An simple and customizable pure javascript function to return an array of objects grouped by the attribute needed in the object
export const groupArrayBy = (arr, groupBy) => {
let newArr = []
arr.map((item) => {
if(item[groupBy]) {
let finded = newArr.filter((newItem) => newItem[groupBy] === item[groupBy])
if(finded.length > 0) {
finded[0].products.push(item)
} else {
newArr.push({category: item[groupBy], products: [item]})
}
}
})
return newArr
}