有人知道一种方法(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'
        }
    ]
}

当前回答

简单的for循环也可以实现:

 const result = {};

 for(const {make, model, year} of cars) {
   if(!result[make]) result[make] = [];
   result[make].push({ model, year });
 }

其他回答

在简单的Javascript中,你可以使用array# reduce对象

Var cars = [{make: 'audi',型号:'r8',年份:'2012'},{make: 'audi',型号:'rs5',年份:'2013'},{make: 'ford',型号:'mustang',年份:'2012'},{make: 'ford',型号:'fusion',年份:'2015'},{make: 'kia',型号:'optima',年份:'2012'}], 结果=汽车。Reduce(函数(r, a) { r (a。Make] = r[a]。Make] || []; r (a.make) .push(一个); 返回r; }, Object.create (null)); console.log(结果); .as-console-wrapper {max-height: 100% !重要;上图:0;}

同意除非经常使用这些库,否则不需要外部库。虽然有类似的解决方案,但我发现其中一些很难遵循。如果您试图理解正在发生的事情,这里有一个带有注释的解决方案的要点。

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

@metakungfu answer略有不同,主要区别在于它从结果对象中省略了原始键,因为在某些情况下对象本身不再需要它,因为它现在在父对象中可用。

const groupBy = (_k, a) => a.reduce((r, {[_k]:k, ...p}) => ({
    ...r, ...{[k]: (
        r[k] ? [...r[k], {...p}] : [{...p}]
    )}
}), {});

考虑到您的原始输入对象:

console.log(groupBy('make', cars));

会导致:

{
  audi: [
    { model: 'r8', year: '2012' },
    { model: 'rs5', year: '2013' }
  ],
  ford: [
    { model: 'mustang', year: '2012' },
    { model: 'fusion', year: '2015' }
  ],
  kia: [
    { model: 'optima', year: '2012' }
  ]
}

另一个解决方案:

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

创建一个可以重用的方法

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