[英]Group array objects so that objects with similar key are not put into the same group
我有以下名为'cars'的数组。我想对数据进行分组,以使具有相似键的对象不会放入group(array)中。
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'
},
];
我如何对数据进行分组,以使具有相同品牌的数组对象不会放入同一组中。结果看起来像这样。
var cars = {
'class_1': [
{ 'make' : 'audi',
'model': 'r8',
'year': '2012'
},{ 'make' : 'ford',
'model': 'mustang',
'year': '2012'
},{
'make': 'kia',
'model': 'optima',
'year': '2012'
}
],
'class_2': [
{
'make' : 'audi',
'model': 'rs5',
'year': '2013'
},{
'make': 'ford',
'model': 'fusion',
'year': '2015'
}
]
}
您可以将Array.reduce()
与helper
数组一起使用Array.reduce()
对项目进行分组。 helper
数组保存每个组中的品牌。 对于每个对象,您可以使用Array.findIndex()
查找不包含make
。 如果不存在,请创建一个新组,然后更新helper
。
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 helper = []; const result = cars.reduce((r, o) => { let i = helper.findIndex((g) => !g[o.make]); if(i === -1) { i = helper.push({ [o.make]: true }); r[`class_${i}`] = [o]; } else { r[`class_${i + 1}`].push(o); helper[i][o.make] = true; } return r; }, Object.create(null)); console.log(result);
首先,你应该组汽车进入一个对象(重点将是make
的汽车和值将是汽车的阵列与make
)。 然后找到那些分组数组中最大数组的长度(这将是类的数量)。 然后通过从每个make
数组乘(如果存在)汽车来make
:
function groupCars(cars) {
// 1. group into an object
var group = cars.reduce(function(acc, car) { // for each car in cars
if(acc.hasOwnProperty(car.make)) { // if there is already an a sub array for this current car's make
acc[car.make].push(car); // push it to that array
} else {
acc[car.make] = [car]; // if not, create a new sub array that initially contains this car
}
return acc;
}, {});
// 2. find the biggest array
var makes = Object.keys(group); // get an array of all the makes (["audi", ...]) which are the keys of the object group
var len = Math.max.apply(null, makes.map(function(make) { return group[make].length; })); // map each make into the length of its array of cars and choose the maximum of those length as len
// 3. make the classes, picking up a car from each array (if it exists)
var res = {}; // our result object
for(var i = 0; i < len; i++) { // for...
var cur = res["class_" + (i + 1)] = []; // make a new class array
makes.forEach(function(make) { // for each make in makes
if(i < group[make].length) { // if the current make's array is not empty yet
cur.push(group[make][i]); // take the car at the current index and push it to the current class
}
});
}
return res;
}
可以使用ES6箭头功能将其缩短:
function groupCars(cars) {
// 1. group into an object
let group = cars.reduce((acc, car) => ((acc.hasOwnProperty(car.make)? acc[car.make].push(car): acc[car.make] = [car]), acc), {});
// 2. find the biggest array
let makes = Object.keys(group);
let len = Math.max.apply(null, makes.map((make) => group[make].length));
// 3. make the classes, picking up a car from each array (if it exists)
let res = {};
for(let i = 0; i < len; i++) {
var cur = res["class_" + (i + 1)] = [];
makes.forEach((make) => i < group[make].length && cur.push(group[make][i]);
}
return res;
}
例:
function groupCars(cars) { let group = cars.reduce((acc, car) => ((acc.hasOwnProperty(car.make)? acc[car.make].push(car): acc[car.make] = [car]), acc), {}); let makes = Object.keys(group); let len = Math.max.apply(null, makes.map((make) => group[make].length)); let res = {}; for(let i = 0; i < len; i++) { var cur = res["class_" + (i + 1)] = []; makes.forEach((make) => i < group[make].length && cur.push(group[make][i]); } return res; } var arr = [{"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(groupCars(arr));
您可以这样做。
// helper function to add single car to single class if possible
function addCarToClass(car, cls) {
// it the class already contains car with that key - fail
for (let i = 0; i < cls.length; i++) {
if (cls[i].make === car.make) return false;
}
// else push it to that class
cls.push(car);
return true;
}
// hepler function to find class to which the car should be placed
function findClassForCar(car, classes) {
let placed = false;
for (let i = 0; i < classes.length; i++) {
if (addCarToClass(car, classes[i])) {
placed = true;
break;
};
}
// if the car wasn't placed, start a new class and place it there
if (!placed) {
let cls = [];
cls.push(car);
classes.push(cls);
}
}
// final function to split cars accordingly
function splitToClasses(cars) {
const classes = [];
for (let i = 0; i < cars.length; i++) {
findClassForCar(cars[i], classes);
}
// format result according to your question
const res = {};
for (let i = 0; i < classes.length; i++) {
res['class_' + i] = classes[i];
}
return res;
}
console.log(splitToClasses(cars));
这不太可能有效,因此,如果您要处理列表中成千上万辆或更多的汽车,则可以尝试查找其他东西。 但是代码很简单:
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 separateMakes = cars => cars.reduce((groupings, car) => { const groups = Object.values(groupings) let group = groups.find(group => group.every(test => test.make != car.make)) || (groupings[`classes_${groups.length + 1}`] = []) group.push(car) return groupings }, {}) console.log(separateMakes(cars))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.