【问题标题】:Combine results from array of objects based on key in nested array of objects [closed]根据嵌套对象数组中的键组合对象数组的结果[关闭]
【发布时间】:2021-06-05 13:22:24
【问题描述】:

我有一组对象,我想根据特定 ID 过滤和组合结果。这是一个例子:

[
    {
        id: 1,
        items: [
            {
                id: 10,
                values: [11],
            },
            {
                id: 20,
                values: [13, 14, 15],
            },
        ],
    },
    {
        id: 2,
        items: [
            {
                id: 10,
                values: [12],
            },
            {
                id: 20,
                values: [13, 15],
            },
        ],
    },
];

这是预期的结果:

[
    {
        id: 10,
        values: [11, 12],
    },
    {
        id: 20,
        values: [13, 14, 15],
    },
];

我还需要过滤重复项。谢谢

注意:如果我想要这个结果怎么办?

[
    {
        // here I want value for id 10 (it will be always one number)
        value: 11,
        // here I want values for id 20 (array of numbers) => remove possible duplicates
        values: [13, 14, 15],
    },
    {
        // here I want value for id 10 (it will be always one number)
        value: 12,
        // here I want values for id 20 (array of numbers) => remove possible duplicates
        values: [13, 15],
    },
];

我尝试了与 Map 相同的方法,但没有成功。基本上我想根据 id 组合值。

【问题讨论】:

标签: javascript arrays javascript-objects


【解决方案1】:
  1. 您可以使用 Array.flatMap 过滤单个数组中的所有 items
  2. 然后使用Array.reduce 重新创建数组,并将基于id 的值推送到新的值对象中
  3. 并使用Array.filter 忽略数组上的重复值
  4. Object.values只返回数组格式的对象值

老年人

const arr = [ { id: 1, items: [ { id: 10, values: [11], }, { id: 20, values: [13, 14, 15], }, ], }, { id: 2, items: [ { id: 10, values: [12], }, { id: 20, values: [13, 15], }, ], }, ];


const res = Object.values(arr.flatMap(({items})=> items)
           .reduce((acc,{id,values})=>{
              acc[id] = acc[id] ?? {id,values:[]}; 
              //check the object exist or not 

              let newArr = acc[id]['values'].concat(values);
              let valArr = newArr.filter((v,i)=>newArr.indexOf(v) === i)
              //remove the duplicates

              acc[id]['values'] = valArr
             return acc
          },{}))

console.log(res)

更新

const arr = [ { id: 1, items: [ { id: 10, values: [11], }, { id: 20, values: [13, 14, 15], }, ], }, { id: 2, items: [ { id: 10, values: [12], }, { id: 20, values: [13, 15], }, ], }, ];


function filterMethod(arr,value,values){
return arr.map(({items})=> ({
              value:detector(items,value)[0],
              values:detector(items,values)
        }))
}

function detector(items,idVal){
  let ind = items.findIndex(({id})=> id === idVal);
  return ind > -1 ? items[ind]['values'] : ['']
}
         
console.log(filterMethod(arr,10,20))

【讨论】:

  • 非常感谢您的帮助。
  • 如果您想要更快的代码,请尝试以下操作: let res = [];让地图=新地图(); arr.flatMap(el => el.items).forEach(el => { map.set(el.id, map.get(el.id) ? [...map.get(el.id), .. .el.values] : el.values); }); map.forEach((value, key) => { res.push({ id: key, values: value.filter(function(item, pos) { return value.indexOf(item) == pos; }) }); })
  • @moustafa Nice.,请作为答案发布,而不是评论。而且您使用的forEach 循环次数更多。我不知道两者的速度差异。我可以知道怎么做吗?
  • @prasanth 我已尽力编辑了问题,但我需要帮助。
  • @marek8623 检查我更新的答案。基于 id 的自动选择是不可能的。所以你将value,values 的 id 作为参数传递。 detector函数验证id是否存在
猜你喜欢
  • 2017-05-09
  • 2018-09-13
  • 2020-03-11
  • 2019-07-09
  • 2020-08-10
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多