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

当前回答

另一个解决方案:

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

其他回答

对于key可以为null的情况,我们希望将它们分组为其他

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'},
            {'make':'kia','model':'optima','year':'2033'},
            {'make':null,'model':'zen','year':'2012'},
            {'make':null,'model':'blue','year':'2017'},

           ];


 result = cars.reduce(function (r, a) {
        key = a.make || 'others';
        r[key] = r[key] || [];
        r[key].push(a);
        return r;
    }, Object.create(null));

使用lodash/fp,你可以使用_.flow()创建一个函数,它首先按键分组,然后映射每个组,并从每个项中省略一个键:

const { flow, groupBy, mapValues, map, omit } = _; const groupAndOmitBy = key => flow( groupBy(key), mapValues(map(omit(key))) ); 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 groupAndOmitMake = groupAndOmitBy('make'); const result = groupAndOmitMake(cars); console.log(result); .as-console-wrapper { max-height: 100% !important; top: 0; } <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

下面是一个受到Java中的collections . groupingby()启发的解决方案:

function groupingBy(list, keyMapper) { 返回列表。reduce((accummalatorMap, currentValue) => { const key = keyMapper(currentValue); 如果(! accummalatorMap.has(键)){ accummalatorMap。集(关键,[currentValue]); }其他{ accummalatorMap。集(键,accummalatorMap.get(关键).push (currentValue)); } 返回accummalatorMap; }, new Map()); }

这将给出一个Map对象。

/ /使用 const cars = groupingBy(cars, car => car.make);

我制定了一个基准测试不使用外部库的每个解决方案的性能。

JSBen.ch

由@Nina Scholz发布的reduce()选项似乎是最佳选项。

下面是您自己的groupBy函数,它是来自https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore的代码的泛化

函数groupBy(xs, f) { 返回x。减少((r, v, i, a、k = f (v)) = > ((r [k] | | (r [k] = [])) .push (v), r), {}); } Const cars = [{make: 'audi',型号:'r8',年份:'2012'},{make: 'audi',型号:'rs5',年份:'2013'},{make: 'ford',型号:'mustang',年份:'2012'},{make: 'ford',型号:'fusion',年份:'2015'},{make: 'kia',型号:'optima',年份:'2012'}]; const result = groupBy(cars, (c) => c.make); console.log(结果);