有人知道一种方法(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'
}
]
}
我喜欢写它没有依赖/复杂性,只是纯粹的简单js。
const mp = {}
const cars = [
{
model: 'Imaginary space craft SpaceX model',
year: '2025'
},
{
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'
}
]
cars.forEach(c => {
if (!c.make) return // exit (maybe add them to a "no_make" category)
if (!mp[c.make]) mp[c.make] = [{ model: c.model, year: c.year }]
else mp[c.make].push({ model: c.model, year: c.year })
})
console.log(mp)
同意除非经常使用这些库,否则不需要外部库。虽然有类似的解决方案,但我发现其中一些很难遵循。如果您试图理解正在发生的事情,这里有一个带有注释的解决方案的要点。
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'
}, ];
/**
* Groups an array of objects by a key an returns an object or array grouped by provided key.
* @param array - array to group objects by key.
* @param key - key to group array objects by.
* @param removeKey - remove the key and it's value from the resulting object.
* @param outputType - type of structure the output should be contained in.
*/
const groupBy = (
inputArray,
key,
removeKey = false,
outputType = {},
) => {
return inputArray.reduce(
(previous, current) => {
// Get the current value that matches the input key and remove the key value for it.
const {
[key]: keyValue
} = current;
// remove the key if option is set
removeKey && keyValue && delete current[key];
// If there is already an array for the user provided key use it else default to an empty array.
const {
[keyValue]: reducedValue = []
} = previous;
// Create a new object and return that merges the previous with the current object
return Object.assign(previous, {
[keyValue]: reducedValue.concat(current)
});
},
// Replace the object here to an array to change output object to an array
outputType,
);
};
console.log(groupBy(cars, 'make', true))
另一个解决方案:
Var汽车= [
{“使”:“奥迪”,“模型”:“r8”,“年”:“2012”},{“使”:“奥迪”,“模型”:“生活费”,“年”:“2013”},
{“使”:“福特”,“模型”:“野马”,“年”:“2012”},{“使”:“福特”,“模型”:“融合”,“年”:“2015”},
{'make': 'kia','model': 'optima','year': '2012'},
];
const reducedCars =汽车。Reduce ((acc, {make, model, year}) => (
{
acc,
[make]: acc[make] ?[…Acc [make], {model, year}]: [{model, year}],
}
), {});
console.log (reducedCars);
Var汽车= [{
:“奥迪”,
模型:“r8”,
:“2012”
},{
:“奥迪”,
模型:“生活费”,
:“2013”
},{
:“福特”,
模型:“野马”,
:“2012”
},{
:“福特”,
模型:“融合”,
:“2015”
},{
:“克钦独立军”,
模型:“最佳状态”,
:“2012”
})。Reduce ((r, car) => {
const {
模型中,
一年,
使
} =汽车;
R [make] =[…]R [make] || [], {
模型中,
一年
});
返回r;
}, {});
console.log(汽车);