-1

我有一个嵌套的对象数组,我想 groupBy id 并形成一个新数组。这是我的数组:

mainArray = [
  { name: 'a',age: 10, company: [ { desc: 'test1' , id: 6 }, { desc: 'testa' , id: 10 }] },
  { name: 'b',age: 20, company: [ { desc: 'test2' , id: 30 }] },
  { name: 'c',age: 40, company: [ { desc: 'test3' , id: 10 }, { desc: 'testc' , id: 30 }] }
]

我可以展平整个阵列,但这似乎不是正确的做法。

我的新数组应该是这样的:

result = [
  comapny_6: [
    {
      name: 'a',
      age: 10,
      desc: 'test1'
    },
  ],
  comapny_10: [
    {
      name: 'a',
      age: 10,
      desc: 'testa'
    },
    {
      name: 'c',
      age: 40,
      desc: 'test3'
    }
  ],

  company_30 :[
    {
      name: 'b',
      age: 20,
      desc: 'test2'
    },
    {
      name: 'c',
      age: 40,
      desc: 'testc'
    }
  ]
]

我愿意接受有关最终数据结构应该是什么样子的建议。底线是我想要 groupBy id,以便我有关于每个公司的信息分开。

4

3 回答 3

1

您可以使用reduce遍历数组并构造所需的对象输出。用于forEach循环company

var mainArray = [{"name":"a","age":10,"company":[{"desc":"test1","id":6},{"desc":"testa","id":10}]},{"name":"b","age":20,"company":[{"desc":"test2","id":30}]},{"name":"c","age":40,"company":[{"desc":"test3","id":10},{"desc":"testc","id":30}]}];

var result = mainArray.reduce((c, {name,age,company}) => {
  company.forEach(({id,desc}) => (c["company_" + id] = c["company_" + id] || []).push({name,age,desc}));
  return c;
}, {});

console.log(result);

于 2019-05-17T16:05:32.267 回答
1

您可以先使用创建一维数组flatMap(),然后使用reduce()来分组

const mainArray = [
  { name: 'a',age: 10, company: [ { desc: 'test1' , id: 6 }, { desc: 'testa' , id: 10 }] },
  { name: 'b',age: 20, company: [ { desc: 'test2' , id: 30 }] },
  { name: 'c',age: 40, company: [ { desc: 'test3' , id: 10 }, { desc: 'testc' , id: 30 }] }
]

const flat = mainArray.flatMap(({company,...rest}) => company.map(a => ({...rest,...a})));

const res = flat.reduce((ac,{id,...rest}) => ((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac),{})
console.log(res)

解释

reduce()is 方法在遍历所有数组后返回单个值。累加器即ac在上述情况下设置为空对象{}(这是传递给函数的第二个参数)

在每次迭代中,我们返回更新后的累加器,ac用于下一次迭代。所以我们从函数返回的是下面的表达式

((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac)

ac[company_${id}]正在使用带有表达式的括号表示法company_${id}。它与

ac["company_" + id]

上面的行检查它是否ac[company_${id}]存在于acthenpush() rest中。

如果ac[company_${id}]尚未创建,则将其设置为空数组,[]然后push()rest其设置为。

最后一部分使用逗号运算符

((ac[`company_${id}`] || (ac[`company_${id}`] = [])).push(rest),ac)

上面的整个表达式将计算为用逗号分隔的最后一个值,,即ac. 因此,在每次迭代中,我们都推rest送到相应的数组并ac在最后返回它。代码相当于

const res = flat.reduce((ac,{id,...rest}) => {
    //check if company id doesnot exist as key in ac then set it empty array
    if(!ac[`company_${id}`]) ac[`company_${id}`] = [];
    //push rest(which will be an object with all the keys expect id)
    ac[`company_${id}`].push(rest)
    //at last return ac
    return ac;
})
于 2019-05-17T16:06:14.477 回答
0

您可以使用Array.reduce并在其中使用Array.forEach在公司数组上实现这一点,如下所示:

let data = [ { name: 'a',age: 10, company: [ { desc: 'test1' , id: 6 }, { desc: 'testa' , id: 10 }] }, { name: 'b',age: 20, company: [ { desc: 'test2' , id: 30 }] }, { name: 'c',age: 40, company: [ { desc: 'test3' , id: 10 }, { desc: 'testc' , id: 30 }] } ] 

let result = data.reduce((r,{ name, age, company }) => {
  company.forEach(({ id, desc }) => 
   r[`company_${id}`] = (r[`company_${id}`] || []).concat({ name, age, desc }))
  return r
}, {})

console.log(result)

于 2019-05-17T16:41:13.020 回答