首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按嵌套数组键对数组进行分组,结果是重复项。

按嵌套数组键对数组进行分组,结果是重复项。
EN

Stack Overflow用户
提问于 2022-04-21 21:29:19
回答 3查看 643关注 0票数 1

这是一个有点棘手的找到正确的词,所以希望展示一些代码将有所帮助。

我有以下(简化)人员和他们的部门的数组。这来自于CMS数据,它允许将一个人添加到多个部门(因此departments是一个数组)。

代码语言:javascript
复制
[
  {
    id: '12345',
    name: 'Person 1',
    jobTitle: 'Engineering director',
    departments: ['Engineering', 'Leadership']
  },
  {
    id: '54321',
    name: 'Person 2',
    jobTitle: 'Junior engineer',
    departments: ['Engineering']
  },
  {
    id: '00001',
    name: 'Person 3',
    jobTitle: 'Founder',
    departments: ['Leadership']
  },
  {
    id: '00099',
    name: 'Person 4',
    jobTitle: 'No department',
    departments: []
  }
]

我所追求的结果是获得departments的唯一值,并为每个数组创建数组,其中包含适当的用户,如下所示:

代码语言:javascript
复制
{
  'Engineering': [
    {
      id: '12345',
      name: 'Person 1',
      jobTitle: 'Engineering director',
      departments: ['Engineering', 'Leadership']
    },
    {
      id: '54321',
      name: 'Person 2',
      jobTitle: 'Junior engineer',
      departments: ['Engineering']
    }
  ],
  'Leadership': [
    {
      id: '12345',
      name: 'Person 1',
      jobTitle: 'Engineering director',
      departments: ['Engineering', 'Leadership']
    },
    {
      id: '00001',
      name: 'Person 3',
      jobTitle: 'Founder',
      departments: ['Leadership']
    }
  ]
}

我的代码中已经有了一个groupBy函数,但它并不完全满足我的要求(因为它并不期望数组作为属性值),所以如果一个person有多个部门,我会得到一个数组,其中两个部门的名称都是串联的,但是我希望在多个数组中出现相同的person

这是我目前的groupBy函数,但现在它分散了我的注意力,而reduce是一个我的大脑一直在挣扎的概念.!

代码语言:javascript
复制
function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

// which I can use like: 

const groupedPeople = Object.entries(groupBy(people, "departments"));

// and it'll return
/*

{
  'Engineering,Leadership': [
    {
      id: '12345',
      name: 'Person 1',
      jobTitle: 'Engineering director',
      departments: ['Engineering', 'Leadership']
    }
  ],
  'Engineering': [
    {
      id: '54321',
      name: 'Person 2',
      jobTitle: 'Junior engineer',
      departments: ['Engineering']
    }
  ],
  'Leadership': [
    {
      id: '00001',
      name: 'Person 3',
      jobTitle: 'Founder',
      departments: ['Leadership']
    }
  ]
}

*/

我觉得我离得很近了,但我的大脑无法投入其中!

代码语言:javascript
复制
const people = [{
    id: '12345',
    name: 'Person 1',
    jobTitle: 'Engineering director',
    departments: ['Engineering', 'Leadership']
  },
  {
    id: '54321',
    name: 'Person 2',
    jobTitle: 'Junior engineer',
    departments: ['Engineering']
  },
  {
    id: '00001',
    name: 'Person 3',
    jobTitle: 'Founder',
    departments: ['Leadership']
  },
  {
    id: '00099',
    name: 'Person 4',
    jobTitle: 'No department',
    departments: []
  }
]

function groupBy(objectArray, property) {
  return objectArray.reduce(function(acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

// which I can use like: 

const groupedPeople = Object.entries(groupBy(people, "departments"));
console.log("Grouped:", groupedPeople);

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-04-21 21:40:30

代码语言:javascript
复制
var key = obj[property];

在代码的这一行中,key变量表示deparments数组,然后将其用作acc[key]。JS是如何将数组转换成字符串作为acc对象的键的,这是通过逗号加入数组的过程。您需要的是遍历数组,而不是:

代码语言:javascript
复制
function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var keys = obj[property];
    keys.forEach(key => {
      if (!acc[key]) {
        acc[key] = [];
      }
      acc[key].push(obj);
    })
    return acc;
  }, {});
}

这种更改将使其对您的用例有效,如果键不是数组,则groupBy函数将不再工作,因此谨慎使用或使其既支持字符串又支持数组。

票数 1
EN

Stack Overflow用户

发布于 2022-04-21 21:44:21

我在我的解决方案中得到了一个递归错误,在将它推入两个不同的数组之前,我不得不对一个对象(JSON.parse(JSON.stringify(obj)))进行深度复制。此外,考虑到您的属性可能是数组,也可能不是数组,我将该部分规范化为:

代码语言:javascript
复制
let keys = Array.isArray(obj[property]) ? obj[property] : [obj[property]];

代码语言:javascript
复制
let people = [{
    id: '12345',
    name: 'Person 1',
    jobTitle: 'Engineering director',
    departments: ['Engineering', 'Leadership']
  },
  {
    id: '54321',
    name: 'Person 2',
    jobTitle: 'Junior engineer',
    departments: ['Engineering']
  },
  {
    id: '00001',
    name: 'Person 3',
    jobTitle: 'Founder',
    departments: ['Leadership']
  },
  {
    id: '00099',
    name: 'Person 4',
    jobTitle: 'No department',
    departments: []
  }
];

function groupBy(objectArray, property) {
  return objectArray.reduce((acc, obj) => {
    let keys = Array.isArray(obj[property]) ? obj[property] : [obj[property]];
    keys.forEach(k => {
      acc[k] = acc[k] || [];
      acc[k].push(JSON.parse(JSON.stringify(obj)))
    })
    return acc;
  }, {});
}

console.log(groupBy(people, "departments"));
console.log(groupBy(people, "jobTitle"));

票数 0
EN

Stack Overflow用户

发布于 2022-04-21 21:55:33

我只更改了3行代码片段,首先将所有内容转换为数组,然后遍历该数组并创建组使代码更容易编写。您还可以检查它是否是数组,并使用if语句编写类似的代码。

代码语言:javascript
复制
const people = [{
    id: '12345',
    name: 'Person 1',
    jobTitle: 'Engineering director',
    departments: ['Engineering', 'Leadership']
  },
  {
    id: '54321',
    name: 'Person 2',
    jobTitle: 'Junior engineer',
    departments: ['Engineering']
  },
  {
    id: '00001',
    name: 'Person 3',
    jobTitle: 'Founder',
    departments: ['Leadership']
  },
  {
    id: '00099',
    name: 'Person 4',
    jobTitle: 'No department',
    departments: []
  }
]

function groupBy(objectArray, property) {
  return objectArray.reduce(function(acc, obj) {
    if (obj[property] === null || obj[property] === undefined) return acc; // if obj[property] is not defined or it's null don't add it to groupts
    if (obj[property].constructor !== Array) obj[property] = [obj[property]] // obj[property] is always an array now
    obj[property].forEach(key => {
      if (!acc[key]) {
        acc[key] = [];
      }
      acc[key].push(obj);
    })
    return acc;
  }, {});
}

// which I can use like: 

const groupedPeople = Object.entries(groupBy(people, "departments"));
console.log("Grouped:", groupedPeople);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71961069

复制
相关文章

相似问题

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