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

其他回答

letfinaldata=[]

let data =[{id:1,name:"meet"},{id:2,name:"raj"},{id:1,name:"hari"},{id:3,name:"hari"},{id:2,name:"ram"}]

data = data.map((item)=> 
{
    return {...item,
        name: [item.name]
    }
}) // Converting the name key from string to array


let temp = [];

for(let i =0 ;i<data.length;i++)
{
    const index = temp.indexOf(data[i].id) // Checking if the object id is already present
    if(index>=0)
    {
        letfinaldata[index].name = [...letfinaldata[index].name,...data[i].name] // If present then append the name to the name of that object
    }
    else{
        temp.push(data[i].id); // Push the checked object id
        letfinaldata.push({...data[i]}) // Push the object
    }
}

console.log(letfinaldata)

输出

[ { id: 1, name: [ 'meet', 'hari' ] },
  { id: 2, name: [ 'raj', 'ram' ] },
  { id: 3, name: [ 'hari' ] } ]
function groupBy(data, property) {
  return data.reduce((acc, obj) => {
    const key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}
groupBy(people, 'age');

这是另一个解决方案。按照要求。

我想创建一个新的汽车对象数组,由make分组:

function groupBy() {
  const key = 'make';
  return cars.reduce((acc, x) => ({
    ...acc,
    [x[key]]: (!acc[x[key]]) ? [{
      model: x.model,
      year: x.year
    }] : [...acc[x[key]], {
      model: x.model,
      year: x.year
    }]
  }), {})
}

输出:

console.log('Grouped by make key:',groupBy())

使用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>

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