首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >一种有效地将对象数组转换为以对象数组为值的分组哈希图的ES2015+方法

一种有效地将对象数组转换为以对象数组为值的分组哈希图的ES2015+方法
EN

Stack Overflow用户
提问于 2019-04-23 02:52:26
回答 2查看 52关注 0票数 0

我正在尝试寻找一种优雅而高效的方法来将对象数组转换为由键(在本例中为"groupByThisKey")索引的对象。一个hashmap,我相信它叫做。

我想出了一个原始版本

下面用一些数据进行了解释:

代码语言:javascript
复制
const arr = [
  {
    id: 1,
    name: "one",
    groupByThisKey: 'groupA'
  },
  {
    id: 2,
    name: "two",
    groupByThisKey: 'groupB'
  },
  {
    id: 3,
    name: "three",
    groupByThisKey: 'groupB'
  },
  {
    id: 4,
    name: "four",
    groupByThisKey: 'groupA'
  }
];

const groupedByKey = {};

arr.map(obj => {
  if (groupedByKey[obj.groupByThisKey])
    groupedByKey[obj.groupByThisKey].push(obj)
  else
    groupedByKey[obj.groupByThisKey] = [obj]
});

console.log(groupedByKey)

它确实给出了所需的输出:

代码语言:javascript
复制
{
  groupA: [
   {
     id: 1,
     name: "one",
     groupByThisKey: 'groupA'
   },
   {
     id: 4,
     name: "four",
     groupByThisKey: 'groupA'
   }
  ],
  groupB: [
   {
     id: 2,
     name: "two",
     groupByThisKey: 'groupB'
   },
   {
     id: 3,
     name: "three",
     groupByThisKey: 'groupB'
   }
  ]
}

但以一种相当原始的方式。我更愿意使用一种更短、更现代的方法来完成这项工作,如果可能的话,可以使用object.assign或reduce,但我不能理解它,因为我需要为每个键使用一个值数组。

我能够找到许多示例,这些示例似乎都适用于每个键只有一个值的用例,但在我的示例中,我需要一个由该键分组的对象的数组,所以我找到的示例只接受最新的值。下面是一个例子:

代码语言:javascript
复制
const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-23 03:02:48

你实现的东西是非常正确的,让我使用一个reducer来消除它的副作用:

代码语言:javascript
复制
const arr = [
  {
    id: 1,
    name: "one",
    groupByThisKey: 'groupA'
  },
  {
    id: 2,
    name: "two",
    groupByThisKey: 'groupB'
  },
  {
    id: 3,
    name: "three",
    groupByThisKey: 'groupB'
  },
  {
    id: 4,
    name: "four",
    groupByThisKey: 'groupA'
  }
];

console.log(arr.reduce((groupedByKey,obj) => {
  if (groupedByKey[obj.groupByThisKey])
    groupedByKey[obj.groupByThisKey].push(obj)
  else
    groupedByKey[obj.groupByThisKey] = [obj]
    
  return groupedByKey;
}, {}));

这就是最fp式的编写方式。不是真正的性能,下面的下一个版本(之后)会有更好的性能,因为在每次迭代中创建对象或数组都不是新的。

代码语言:javascript
复制
const arr = [
    {
        id: 1,
        name: "one",
        groupByThisKey: 'groupA'
    },
    {
        id: 2,
        name: "two",
        groupByThisKey: 'groupB'
    },
    {
        id: 3,
        name: "three",
        groupByThisKey: 'groupB'
    },
    {
        id: 4,
        name: "four",
        groupByThisKey: 'groupA'
    }
];

console.log(arr.reduce(
    (groups, x) => 
        ({ 
            ...groups, 
            [x.groupByThisKey]: [
                ...(groups[x.groupByThisKey] || []),
                x
            ]
        })
    , {}
))

更简单的版本,与上面的逻辑相同:

代码语言:javascript
复制
const arr = [
    {
        id: 1,
        name: "one",
        groupByThisKey: 'groupA'
    },
    {
        id: 2,
        name: "two",
        groupByThisKey: 'groupB'
    },
    {
        id: 3,
        name: "three",
        groupByThisKey: 'groupB'
    },
    {
        id: 4,
        name: "four",
        groupByThisKey: 'groupA'
    }
];

console.log(arr.reduce(
    (groups, x) => {
        let key = x.groupByThisKey;
        
        if (groups[key] === undefined)
            groups[key] = [];
            
        groups[key].push(x);
        
        return groups;
    }, {}
))

票数 2
EN

Stack Overflow用户

发布于 2019-04-23 02:59:21

现代的方式是使用Map,而不是对象:

代码语言:javascript
复制
const groupedByKey = new Map();
for (const obj of arr) {
  if (!groupedByKey.has(obj.groupByThisKey))
    groupedByKey.set(obj.groupByThisKey, []);
  groupedByKey.get(obj.groupByThisKey).push(obj);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55799551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档