簡體   English   中英

對數組對象進行分組,以使具有相似鍵的對象不會放入同一組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM