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

当前回答

完全没有理由下载第三方库来解决这个简单的问题,就像上面的解决方案所建议的那样。

在es6中按特定键对对象列表进行分组的单行版本:

const groupByKey = (list, key) => list.reduce((hash, obj) => ({...hash, [obj[key]]:( hash[obj[key]] || [] ).concat(obj)}), {})

较长的版本过滤掉没有键的对象:

function groupByKey(array, key) { return array .reduce((hash, obj) => { if(obj[key] === undefined) return hash; return Object.assign(hash, { [obj[key]]:( hash[obj[key]] || [] ).concat(obj)}) }, {}) } 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'}]; console.log(groupByKey(cars, 'make'))

注意:原来的问题似乎是问如何按制造商对汽车进行分组,但省略了每组中的制造商。因此,如果没有第三方库,简单的回答是这样的:

const groupByKey = (list, key, {omitKey=false}) => list.reduce((hash, {[key]:value, ...rest}) => ({...hash, [value]:( hash[value] || [] ).concat(omitKey ? {...rest} : {[key]:value, ...rest})} ), {}) 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'}]; console.log(groupByKey(cars, 'make', {omitKey:true}))

其他回答

添加Array.prototype.group和Array.prototype.groupToMap的提案现在处于阶段3!

当它达到阶段4并在大多数主流浏览器上实现时,你将能够这样做:

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 grouped = cars.group(item => item.make);
console.log(grouped);

这将输出:

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

在那之前,你可以使用这个core-js polyfill:

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 grouped = cars.group(item => item.make); //console.log(grouped); // Optional: remove the "make" property from resulting object const entriesUpdated = Object .entries(grouped) .map(([key, value]) => [ key, value.map(({make, ...rest}) => rest) ]); const noMake = Object.fromEntries(entriesUpdated); console.log(noMake); <script src="https://unpkg.com/core-js-bundle@3.26.1/minified.js"></script>

根据@Jonas_Wilms的回答,如果你不想输入所有的字段:

    var result = {};

    for ( let { first_field, ...fields } of your_data ) 
    { 
       result[first_field] = result[first_field] || [];
       result[first_field].push({ ...fields }); 
    }

我没有做任何基准测试,但我相信使用for循环会比这个答案中建议的任何方法都更有效。

const reGroup = (list, key) => {
    const newGroup = {};
    list.forEach(item => {
        const newItem = Object.assign({}, item);
        delete newItem[key];
        newGroup[item[key]] = newGroup[item[key]] || [];
        newGroup[item[key]].push(newItem);
    });
    return newGroup;
};
const animals = [
  {
    type: 'dog',
    breed: 'puddle'
  },
  {
    type: 'dog',
    breed: 'labradoodle'
  },
  {
    type: 'cat',
    breed: 'siamese'
  },
  {
    type: 'dog',
    breed: 'french bulldog'
  },
  {
    type: 'cat',
    breed: 'mud'
  }
];
console.log(reGroup(animals, 'type'));
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'
  },
];

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

我喜欢写它没有依赖/复杂性,只是纯粹的简单js。

const mp = {} const cars = [ { model: 'Imaginary space craft SpaceX model', year: '2025' }, { 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' } ] cars.forEach(c => { if (!c.make) return // exit (maybe add them to a "no_make" category) if (!mp[c.make]) mp[c.make] = [{ model: c.model, year: c.year }] else mp[c.make].push({ model: c.model, year: c.year }) }) console.log(mp)

您正在寻找_.groupBy()。

如果需要,从对象中删除分组的属性应该很简单:

Const cars = [{ “做”:“奥迪”, “模型”:“r8”, “年”:“2012” },{ “做”:“奥迪”, “模型”:“生活费”, “年”:“2013” },{ “做”:“福特”, “模型”:“野马”, “年”:“2012” },{ “做”:“福特”, “模型”:“融合”, “年”:“2015” },{ “做”:“克钦独立军”, “模型”:“最佳状态”, “年”:“2012” }); Const分组= _。groupBy(cars, car => car.make); console.log(分组); < script src = " https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js " > < /脚本>