有人知道一种方法(lodash如果可能的话)通过对象键分组对象数组,然后根据分组创建一个新的对象数组吗?例如,我有一个汽车对象数组:
const cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
我想创建一个新的汽车对象数组,由make分组:
const cars = {
'audi': [
{
'model': 'r8',
'year': '2012'
}, {
'model': 'rs5',
'year': '2013'
},
],
'ford': [
{
'model': 'mustang',
'year': '2012'
}, {
'model': 'fusion',
'year': '2015'
}
],
'kia': [
{
'model': 'optima',
'year': '2012'
}
]
}
Prototype version using ES6 as well.
Basically this uses the reduce function to pass in an accumulator and current item, which then uses this to build your "grouped" arrays based on the passed in key. the inner part of the reduce may look complicated but essentially it is testing to see if the key of the passed in object exists and if it doesn't then create an empty array and append the current item to that newly created array otherwise using the spread operator pass in all the objects of the current key array and append current item. Hope this helps someone!.
Array.prototype.groupBy = function(k) {
return this.reduce((acc, item) => ((acc[item[k]] = [...(acc[item[k]] || []), item]), acc),{});
};
const projs = [
{
project: "A",
timeTake: 2,
desc: "this is a description"
},
{
project: "B",
timeTake: 4,
desc: "this is a description"
},
{
project: "A",
timeTake: 12,
desc: "this is a description"
},
{
project: "B",
timeTake: 45,
desc: "this is a description"
}
];
console.log(projs.groupBy("project"));
const reGroup = (list, key) => {
const newGroup = {};
list.forEach(item => {
const newItem = Object.assign({}, item);
delete newItem[key];
newGroup[item[key]] = newGroup[item[key]] || [];
newGroup[item[key]].push(newItem);
});
return newGroup;
};
const animals = [
{
type: 'dog',
breed: 'puddle'
},
{
type: 'dog',
breed: 'labradoodle'
},
{
type: 'cat',
breed: 'siamese'
},
{
type: 'dog',
breed: 'french bulldog'
},
{
type: 'cat',
breed: 'mud'
}
];
console.log(reGroup(animals, 'type'));
const cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
console.log(reGroup(cars, 'make'));
使用lodash/fp,你可以使用_.flow()创建一个函数,它首先按键分组,然后映射每个组,并从每个项中省略一个键:
const { flow, groupBy, mapValues, map, omit } = _;
const groupAndOmitBy = key => flow(
groupBy(key),
mapValues(map(omit(key)))
);
const cars = [{ make: 'audi', model: 'r8', year: '2012' }, { make: 'audi', model: 'rs5', year: '2013' }, { make: 'ford', model: 'mustang', year: '2012' }, { make: 'ford', model: 'fusion', year: '2015' }, { make: 'kia', model: 'optima', year: '2012' }];
const groupAndOmitMake = groupAndOmitBy('make');
const result = groupAndOmitMake(cars);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>