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

当前回答

@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' }
  ]
}

其他回答

我用REAL GROUP BY作为JS数组的例子和这个任务完全一样

const inputArray = [ { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" }, { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" }, { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" }, { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" }, { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" } ]; var outObject = inputArray.reduce(function(a, e) { // GROUP BY estimated key (estKey), well, may be a just plain key // a -- Accumulator result object // e -- sequentally checked Element, the Element that is tested just at this itaration // new grouping name may be calculated, but must be based on real value of real field let estKey = (e['Phase']); (a[estKey] ? a[estKey] : (a[estKey] = null || [])).push(e); return a; }, {}); console.log(outObject);

您可以尝试在调用per iteration的函数中修改对象_。groupBy func。 注意,源数组改变了它的元素!

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

只需简单的forEach循环就可以在这里工作,不需要任何库

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' }, ]; let ObjMap ={}; cars.forEach(element => { var makeKey = element.make; if(!ObjMap[makeKey]) { ObjMap[makeKey] = []; } ObjMap[makeKey].push({ model: element.model, year: element.year }); }); console.log(ObjMap);

const groupBy = (array, callback) => {
  const groups = {};
  
  array.forEach((element) => {
    const groupName = callback(element);
    if (groupName in groups) {
      groups[groupName].push(element);
    } else {
      groups[groupName] = [element];
    }
  });
  
  return groups;
};

或者花哨的裤子:

(() => {
  Array.prototype.groupBy = function (callback) {
    const groups = {};
    this.forEach((element, ...args) => {
      const groupName = callback(element, ...args);
      if (groupName in groups) {
        groups[groupName].push(element);
      } else {
        groups[groupName] = [element];
      }
    });

    return groups;
  };
})();

const res = [{ name: 1 }, { name: 1 }, { name: 0 }].groupBy(({ name }) => name);

// const res = {
//   0: [{name: 0}],
//   1: [{name: 1}, {name: 1}]
// }

这是一个MDN阵列的填充。groupBy函数。

Prototype version using ES6 as well. Basically this uses the reduce function to pass in an accumulator and current item, which then uses this to build your "grouped" arrays based on the passed in key. the inner part of the reduce may look complicated but essentially it is testing to see if the key of the passed in object exists and if it doesn't then create an empty array and append the current item to that newly created array otherwise using the spread operator pass in all the objects of the current key array and append current item. Hope this helps someone!.

Array.prototype.groupBy = function(k) {
  return this.reduce((acc, item) => ((acc[item[k]] = [...(acc[item[k]] || []), item]), acc),{});
};

const projs = [
  {
    project: "A",
    timeTake: 2,
    desc: "this is a description"
  },
  {
    project: "B",
    timeTake: 4,
    desc: "this is a description"
  },
  {
    project: "A",
    timeTake: 12,
    desc: "this is a description"
  },
  {
    project: "B",
    timeTake: 45,
    desc: "this is a description"
  }
];

console.log(projs.groupBy("project"));