javascript使用ID列表从嵌套数组中提取对象

时间:2018-09-04 14:26:27

标签: javascript arrays multidimensional-array ecmascript-6

我有一个ID列表作为参考,并且我有一个对象,其中包含多个具有对象数组的对象。

我想以最快的方式在列表中创建具有相应ID的对象数组。

const data = {
  "items": {
    "item1": [{
        "id": "id1",
        "info": "info1"
      },
      {
        "id": "id2",
        "info": "info22"
      }
    ],
    "item20": [{
      "id": "id3",
      "info": "info5"
    }],
    "item5": [{
        "id": "id4",
        "info": "info6"
      },
      {
        "id": "id5",
        "info": "info7"
      }
    ]
  }
};

const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val) {

  const match = Object.keys(data.items).map(item => {
    return data.items[item].find(obj => obj.id === val)
  });
  results.push(match)
})
console.log('final: ', results)

当前没有返回我想要的东西。 预期结果将是:

[
    {
      "id": "id2",
      "info": "info22"
    },
    {
        "id": "id4",
        "info": "info6"
    }
]

更新:

如果数据本身是一个对象数组,而我们想对每个对象都做同样的事情呢?

    const data = [{
      "otherStuff": "otherB",
      "items": {
        "item1": [{
            "id": "id1",
            "info": "info1"
          },
          {
            "id": "id2",
            "info": "info22"
          }
        ],
        "item20": [{
          "id": "id3",
          "info": "info5"
        }],
        "item5": [{
            "id": "id4",
            "info": "info6"
          },
          {
            "id": "id5",
            "info": "info7"
          }
        ]
      }
    }, {
      "otherStuff": "otherA",
      "items": {
        "item1": [{
            "id": "id1",
            "info": "info10000"
          },
          {
            "id": "id2",
            "info": "info220000"
          }
        ],
        "item20": [{
          "id": "id3",
          "info": "info5000"
        }],
        "item5": [{
            "id": "id4",
            "info": "info60000"
          },
          {
            "id": "id5",
            "info": "info7000"
          }
        ]
      }
    }];


const keep = ['id4', 'id2'];
const results = [];

    keep.forEach(function(val) {
      data.forEach(function(entry){
          Object.keys(entry.items).forEach(item => {
            var match = entry.items[item].find(obj => obj.id === val);
            if (match) {
              results.push(match)
            }
          });
      });
    })
    
    console.log(results)

,输出应为:

[
    {
        "otherStuff": "otherB",
        "items": [
                {
                      "id": "id2",
                      "info": "info22"
                },
                {
                    "id": "id4",
                    "info": "info6"
            }
        ]
    },
    {
        "otherStuff": "otherA",
        "items": [
                {
                      "id": "id2",
                      "info": "info220000"
                },
                {
                    "id": "id4",
                    "info": "info60000"
            }
        ]
    }
]

结果不一样。

5 个答案:

答案 0 :(得分:3)

如果将Set用作保留的ID,则会保存一次O(n)遍历:

 const keep = new Set(['id4', 'id2']);

 const result = [];

 for(const items of Object.values(data.items))
   for(const item of items)
     if(keep.has(item.id))
       result.push(item);

答案 1 :(得分:1)

您不需要使用map()。只需在要保留的对象键上使用forEach()循环,然后找到匹配的对象,即可将其推入结果数组。

const data = {
  "items": {
    "item1": [{
        "id": "id1",
        "info": "info1"
      },
      {
        "id": "id2",
        "info": "info22"
      }
    ],
    "item20": [{
      "id": "id3",
      "info": "info5"
    }],
    "item5": [{
        "id": "id4",
        "info": "info6"
      },
      {
        "id": "id5",
        "info": "info7"
      }
    ]
  }
};

const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val) {
  Object.keys(data.items).forEach(item => {
    var match = data.items[item].find(obj => obj.id === val);
    if (match) {
      results.push(match)
    }
  });
})
console.log('final: ', results)

答案 2 :(得分:1)

items是一个对象&item1item20是键。因此,您可以执行Object.values并对其应用reduce函数,以得到一个由所有对象组成的数组。无需迭代keep数组并从单个数组中过滤出所需的元素。

const data = {
  "items": {
    "item1": [{
        "id": "id1",
        "info": "info1"
      },
      {
        "id": "id2",
        "info": "info22"
      }
    ],
    "item20": [{
      "id": "id3",
      "info": "info5"
    }],
    "item5": [{
        "id": "id4",
        "info": "info6"
      },
      {
        "id": "id5",
        "info": "info7"
      }
    ]
  }
};



const keep = ['id4', 'id2'];
let getAllObjectValues = Object.values(data.items).reduce(function(acc, curr) {
  curr.forEach((elem) => {
    acc.push(elem)
  })
  return acc;
}, []);

let k = keep.map(function(item) {
  return getAllObjectValues.filter(function(val) {
    return item === val.id
  })[0]

})
console.log(k)

答案 3 :(得分:0)

您在地图函数中使用了赋值运算符而不是等价运算符,请更改为:

const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val){
    const match = Object.keys(data.items).map(item => {
        return data.items[item].find(obj => obj.id === val)
    });
    results.push(match)
})
console.log('final: ', results)    

答案 4 :(得分:0)

使用reducefilter的组合,您可以迭代每个子数组,以检查是否应保留该值。

const data = {
  "items": {
    "item1": [
      {
        "id": "id1",
        "info": "info1"
      },
      {
        "id": "id2",
        "info": "info22"
      }
    ],
    "item20": [
      {
        "id": "id3",
        "info": "info5"
      }
    ],
    "item5": [
      {
        "id": "id4",
        "info": "info6"
      },
      {
        "id": "id5",
        "info": "info7"
      }
    ]
  }
};

const keep = ['id4', 'id2'];
const filter = el => {
  return keep.indexOf(el.id) >= 0;
};

const reducer = (accumulator, currentValue) => { 
  return accumulator = accumulator.concat(data.items[currentValue].filter(filter));
};

let results = Object.keys(data.items).reduce(reducer, []);

console.log('final: ', results);