数组如何按两个属性分组? [英] How can an array be grouped by two properties?

查看:91
本文介绍了数组如何按两个属性分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

const arr = [{
  group: 1,
  question: {
    templateId: 100
  }
}, {
  group: 2,
  question: {
    templateId: 200
  }
}, {
  group: 1,
  question: {
    templateId: 100
  }
}, {
  group: 1,
  question: {
    templateId: 300
  }
}];

预期结果: const result = groupBy(arr, 'group', 'question.templateId');

const result = [
  [{
    group: 1,
    question: {
      templateId: 100
    }
  }, {
    group: 1,
    question: {
      templateId: 100
    }
  }],
  [{
    group: 1,
    question: {
      templateId: 300
    }
  }],
  [{
    group: 2,
    question: {
      templateId: 200
    }
  }]
];


到目前为止:我可以使用


So far: I am able to group the result by a single property using Array.prototype.reduce().

function groupBy(arr, key) {
  return [...arr.reduce((accumulator, currentValue) => {
    const propVal = currentValue[key],
      group = accumulator.get(propVal) || [];
    group.push(currentValue);
    return accumulator.set(propVal, group);
  }, new Map()).values()];
}

const arr = [{
  group: 1,
  question: {
    templateId: 100
  }
}, {
  group: 2,
  question: {
    templateId: 200
  }
}, {
  group: 1,
  question: {
    templateId: 100
  }
}, {
  group: 1,
  question: {
    templateId: 300
  }
}];

const result = groupBy(arr, 'group');

console.log(result);

推荐答案

我建议传递一个回调函数而不是属性名,这使您可以轻松地进行两级访问:

I would recommend to pass a callback function instead of a property name, this allows you to do the two-level-access easily:

function groupBy(arr, key) {
  return Array.from(arr.reduce((accumulator, currentValue) => {
    const propVal = key(currentValue),
//                  ^^^^            ^
          group = accumulator.get(propVal) || [];
    group.push(currentValue);
    return accumulator.set(propVal, group);
  }, new Map()).values());
}

现在您可以执行groupBy(arr, o => o.group)groupBy(arr, o => o.question.templateId).

要获得预期结果,您所需要做的就是将第一个属性分组,然后将第二个属性分组:

All you need to do for getting to your expected result is group by the first property and then group each result by the second property:

function concatMap(arr, fn) {
  return [].concat(...arr.map(fn));
}
const result = concatMap(groupBy(arr, o => o.group), res =>
  groupBy(res, o => o.question.templateId)
);

这篇关于数组如何按两个属性分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆