javascript - 数组如何按两个属性分组?

标签 javascript arrays ecmascript-6

例如:

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
    }
  }]
];

到目前为止:我可以使用 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);

最佳答案

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

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)

要获得预期结果,您需要做的就是按第一个属性分组,然后按第二个属性对每个结果进行分组:

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

关于javascript - 数组如何按两个属性分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43125781/

相关文章:

javascript - 使用 parseint 比较 javascript 中的 2 个数字

javascript - 浏览器收到 404 请求,但可与 Postman 应用程序一起使用

javascript - rails 4 : Normal CSS/JS development workflow for asset pipeline?

JavaScript 数组表达式

JavaScript:关联数组和映射

javascript - 每个选择器的 jQuery onclick

C 从函数返回 char 数组

JavaScript 在字符串的 2 个字符后添加空格但忽略换行符

javascript - 在扩展 Controller (ES6)中注入(inject)模块导致未知提供者错误

javascript - JS 将未定义值转为空字符串