如何按键对对象数组进行分组?

时间:2022-02-01 13:19:39

Does anyone know of a (lodash if possible too) way to group an array of objects by an object key then create a new array of objects based on the grouping? For example, I have an array of car objects:

有没有人知道一种(如果可能的话,也叫lodash)方法,通过一个对象键对一个对象数组进行分组,然后根据这个分组创建一个新的对象数组?例如,我有一个汽车对象数组:

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

I want to make a new array of car objects that's grouped by make:

我想要制造一组新的汽车对象,它们是由make组成的:

var cars = {
    'audi': [
        {
            'model': 'r8',
            'year': '2012'
        }, {
            'model': 'rs5',
            'year': '2013'
        },
    ],

    'ford': [
        {
            'model': 'mustang',
            'year': '2012'
        }, {
            'model': 'fusion',
            'year': '2015'
        }
    ],

    'kia': [
        {
            'model': 'optima',
            'year': '2012'
        }
    ]
}

6 个解决方案

#1


22  

Timo's answer is how I would do it. Simple _.groupBy, and allow some duplications in the objects in the grouped structure.

蒂莫的回答是我该怎么做。简单的_。groupBy,并允许对分组结构中的对象进行重复。

However the OP also asked for the duplicate make keys to be removed. If you wanted to go all the way:

但是OP也要求删除重复的make键。如果你想一直走下去:

var grouped = _.mapValues(_.groupBy(cars, 'make'),
                          clist => clist.map(car => _.omit(car, 'make')));

console.log(grouped);

Yields:

收益率:

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

If you wanted to do this using Underscore.js, note that its version of _.mapValues is called _.mapObject.

如果你想用下划线做这个。注意,它的版本是_。mapValues叫做_.mapObject。

#2


77  

In plain Javascript, you could use Array#reduce with an object

在普通的Javascript中,可以使用数组#reduce和对象

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(function (r, a) {
        r[a.make] = r[a.make] || [];
        r[a.make].push(a);
        return r;
    }, Object.create(null));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

#3


25  

You are looking for _.groupBy().

您正在查找_.groupBy()。

Removing the property you are grouping by from the objects should be trivial if required:

如果需要,从对象中删除正在分组的属性应该是微不足道的:

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 grouped = _.groupBy(cars, function(car) {
  return car.make;
});

console.log(grouped);
<script src='https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js'></script>


As a bonus, you get even nicer syntax with ES6 arrow functions:

作为奖励,您可以使用ES6箭头函数获得更好的语法:

const grouped = _.groupBy(cars, car => car.make);

#4


8  

The short version in es6:

es6的简短版本:

result = cars.reduce((h, a) => Object.assign(h, { [a.make]:( h[a.make] || [] ).concat(a) }), {})

#5


2  

You can try to modify the object inside the function called per iteration by _.groupBy func. Notice that the source array change his elements!

您可以尝试修改函数中每个迭代调用_的对象。groupBy func。注意,源数组改变了元素!

var res = _.groupBy(cars,(car)=>{
    const makeValue=car.make;
    delete car.make;
    return makeValue;
})
console.log(res);
console.log(cars);

#6


2  

Here is your very own groupBy function which is a generalization of the code from: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore

这是您自己的groupBy函数,它是对代码的概括:https://github.com/you- need/ you-don -need - lodash-_下划线

function groupBy(xs, f) {
  return xs.reduce((r, v, i, a, k = f(v)) => ((r[k] || (r[k] = [])).push(v), r), {});
}

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 = groupBy(cars, (c) => c.make);
console.log(result);

#1


22  

Timo's answer is how I would do it. Simple _.groupBy, and allow some duplications in the objects in the grouped structure.

蒂莫的回答是我该怎么做。简单的_。groupBy,并允许对分组结构中的对象进行重复。

However the OP also asked for the duplicate make keys to be removed. If you wanted to go all the way:

但是OP也要求删除重复的make键。如果你想一直走下去:

var grouped = _.mapValues(_.groupBy(cars, 'make'),
                          clist => clist.map(car => _.omit(car, 'make')));

console.log(grouped);

Yields:

收益率:

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

If you wanted to do this using Underscore.js, note that its version of _.mapValues is called _.mapObject.

如果你想用下划线做这个。注意,它的版本是_。mapValues叫做_.mapObject。

#2


77  

In plain Javascript, you could use Array#reduce with an object

在普通的Javascript中,可以使用数组#reduce和对象

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(function (r, a) {
        r[a.make] = r[a.make] || [];
        r[a.make].push(a);
        return r;
    }, Object.create(null));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

#3


25  

You are looking for _.groupBy().

您正在查找_.groupBy()。

Removing the property you are grouping by from the objects should be trivial if required:

如果需要,从对象中删除正在分组的属性应该是微不足道的:

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 grouped = _.groupBy(cars, function(car) {
  return car.make;
});

console.log(grouped);
<script src='https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js'></script>


As a bonus, you get even nicer syntax with ES6 arrow functions:

作为奖励,您可以使用ES6箭头函数获得更好的语法:

const grouped = _.groupBy(cars, car => car.make);

#4


8  

The short version in es6:

es6的简短版本:

result = cars.reduce((h, a) => Object.assign(h, { [a.make]:( h[a.make] || [] ).concat(a) }), {})

#5


2  

You can try to modify the object inside the function called per iteration by _.groupBy func. Notice that the source array change his elements!

您可以尝试修改函数中每个迭代调用_的对象。groupBy func。注意,源数组改变了元素!

var res = _.groupBy(cars,(car)=>{
    const makeValue=car.make;
    delete car.make;
    return makeValue;
})
console.log(res);
console.log(cars);

#6


2  

Here is your very own groupBy function which is a generalization of the code from: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore

这是您自己的groupBy函数,它是对代码的概括:https://github.com/you- need/ you-don -need - lodash-_下划线

function groupBy(xs, f) {
  return xs.reduce((r, v, i, a, k = f(v)) => ((r[k] || (r[k] = [])).push(v), r), {});
}

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 = groupBy(cars, (c) => c.make);
console.log(result);