简体   繁体   English

对数组对象进行分组,以使具有相似键的对象不会放入同一组

[英]Group array objects so that objects with similar key are not put into the same group

I have the following array called 'cars'.I want to group data so that objects with similar key are not put into the group(array). 我有以下名为'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'
},
];

How do i group the data so that array objects with same make are not put into the same group.The result would look like this. 我如何对数据进行分组,以使具有相同品牌的数组对象不会放入同一组中。结果看起来像这样。

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'
    }
]
}

You can use Array.reduce() with a helper array to group the items. 您可以将Array.reduce()helper数组一起使用Array.reduce()对项目进行分组。 The helper array holds the makes that are in each group. helper数组保存每个组中的品牌。 For each object, you Array.findIndex() to find a group that doesn't include the make . 对于每个对象,您可以使用Array.findIndex()查找不包含make If none exists, and a new group, and update the helper . 如果不存在,请创建一个新组,然后更新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); 

First, you should group the cars into an object (the key will be the make of the car and the value will be the array of cars with that make ). 首先,你应该组汽车进入一个对象(重点将是make的汽车和值将是汽车的阵列与make )。 Then find the length of the biggest array among those grouped arrays (which will be the number of the classes). 然后找到那些分组数组中最大数组的长度(这将是类的数量)。 Then make the classes by taking (if exists) a car from each make array: 然后通过从每个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;
}

which can be made shorter using ES6 arrow functions: 可以使用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;
}

Example: 例:

 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)); 

You can do it like this. 您可以这样做。

// 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));

This is not likely to be efficient, so if you're dealing with hundreds of thousands or more cars in your list, you might try to find something else. 这不太可能有效,因此,如果您要处理列表中成千上万辆或更多的汽车,则可以尝试查找其他东西。 But the code is pretty simple: 但是代码很简单:

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM