有人知道一种方法(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'
}
]
}
我喜欢@metakunfu的答案,但它并没有提供预期的输出。
下面是在最终的JSON有效负载中去除“make”的更新。
var 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'
},
];
result = cars.reduce((h, car) => Object.assign(h, { [car.make]:( h[car.make] || [] ).concat({model: car.model, year: car.year}) }), {})
console.log(JSON.stringify(result));
输出:
{
"audi":[
{
"model":"r8",
"year":"2012"
},
{
"model":"rs5",
"year":"2013"
}
],
"ford":[
{
"model":"mustang",
"year":"2012"
},
{
"model":"fusion",
"year":"2015"
}
],
"kia":[
{
"model":"optima",
"year":"2012"
}
]
}
这是一个通用函数,将返回Array groupBy自己的键。
const getSectionListGroupedByKey = < T > (
property: keyof T,
List: Array < T >
): Array < {
title: T[keyof T];data: Array < T >
} > => {
const sectionList: Array < {
title: T[keyof T];data: Array < T >
} > = [];
if (!property || !List ? .[0] ? .[property]) {
return [];
}
const groupedTxnListMap: Map < T[keyof T], Array < T >> = List.reduce((acc, cv) => {
const keyValue: T[keyof T] = cv[property];
if (acc.has(keyValue)) {
acc.get(keyValue) ? .push(cv);
} else {
acc.set(keyValue, [cv]);
}
return acc;
}, new Map < T[keyof T], Array < T >> ());
groupedTxnListMap.forEach((value, key) => {
sectionList.push({
title: key,
data: value
});
});
return sectionList;
};
// Example
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 result = getSectionListGroupedByKey('make', cars);
console.log('result: ', result)
同意除非经常使用这些库,否则不需要外部库。虽然有类似的解决方案,但我发现其中一些很难遵循。如果您试图理解正在发生的事情,这里有一个带有注释的解决方案的要点。
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))
创建一个可以重用的方法
Array.prototype.groupBy = function(prop) {
return this.reduce(function(groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
};
下面你可以根据任何标准进行分组
const groupByMake = cars.groupBy('make');
console.log(groupByMake);
var 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'
},
];
//re-usable method
Array.prototype.groupBy = function(prop) {
return this.reduce(function(groups, item) {
const val = item[prop]
groups[val] = groups[val] || []
groups[val].push(item)
return groups
}, {})
};
// initiate your groupBy. Notice the recordset Cars and the field Make....
const groupByMake = cars.groupBy('make');
console.log(groupByMake);
//At this point we have objects. You can use Object.keys to return an array
您正在寻找_.groupBy()。
如果需要,从对象中删除分组的属性应该很简单:
Const cars = [{
“做”:“奥迪”,
“模型”:“r8”,
“年”:“2012”
},{
“做”:“奥迪”,
“模型”:“生活费”,
“年”:“2013”
},{
“做”:“福特”,
“模型”:“野马”,
“年”:“2012”
},{
“做”:“福特”,
“模型”:“融合”,
“年”:“2015”
},{
“做”:“克钦独立军”,
“模型”:“最佳状态”,
“年”:“2012”
});
Const分组= _。groupBy(cars, car => car.make);
console.log(分组);
< script src = " https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js " > < /脚本>