简体   繁体   English

如何在数组项的第二个对象中查找第一个数组项并从第二个对象返回匹配项

[英]How to find first array items in second object of array items and return matched items from second object

How to find first array items in second object of array items and return matched items from second object using JavaScript.如何在数组项的第二个对象中查找第一个数组项并使用 JavaScript 从第二个对象返回匹配的项。

First Array:第一个数组:

const firstArr = ["foo", "bar"];

Second Object:第二个对象:

const secondObj = {
  "items": [{
    "name": "First item",
    "labels":["foo"]
  },
  {
    "name": "Second item",
    "labels":["foo", "bar"]
  },
  {
    "name": "Third item",
    "labels":["baz"]
  }]
}

Expected:预期的:

{
  "items": [{
    "name": "First item",
    "labels":["foo"]
  },
  {
    "name": "Second item",
    "labels":["foo", "bar"]
  }]
}

I tried something like the following;我尝试了以下内容;

function updatedVersion() {
  var thirdArr = [];
  for (var array of firstArr) {
    if (secondObj) {
      for (var obj of secondObj.items) {
        for (var label of obj.labels) {
          if (array === label) {
            thirdArr.push(obj);
          }
        }
      }
    }
  }
  return thirdArr;
};

You can filter .data with ( Array#filter ) to produce an array of objects based on membership ( Array#some ) by the .labels array ( Array#includes ), then re-build the result object you want afterwards or re-attach the filtered array to .items :您可以使用( Array#filter )过滤.data以通过.labels数组( Array#includes )根据成员资格( Array#some )生成.labels数组,然后重新构建您想要的结果对象或重新附加过滤后的数组到.items

 const firstArr = ["foo", "bar"]; const secondObj = { "items": [{ "name": "First item", "labels":["foo"] }, { "name": "Second item", "labels":["foo", "bar"] }, { "name": "Third item", "labels":["baz"] }] }; secondObj.items = secondObj.items.filter(({labels}) => labels.some(e => firstArr.includes(e)) ); console.log(secondObj);

Note that we're traversing firstArr many times for a complexity of请注意,为了复杂性,我们多次遍历firstArr

O(data.length * firstArr.length * max(data[_].labels.length))

If you make needles a Set and use .has you have如果你把needles做成一套并使用.has你有

O(firstArr.length + data.length * max(data[_].labels.length))

assuming constant time lookups on the set.假设在集合上进行恒定时间查找。 This is premature optimization if your structures are small, and the cost of the Set allocation adds overhead.如果您的结构很小,这是过早的优化,并且Set分配的成本会增加开销。

Similarly, you could make each labels array a Set and cut costs there if it makes sense to do so for your application.同样,如果对您的应用程序有意义,您可以将每个labels数组Set一个Set并在那里削减成本。

 const firstArr = ["foo", "bar"]; const secondObj = { "items": [{ "name": "First item", "labels":["foo"] }, { "name": "Second item", "labels":["foo", "bar"] }, { "name": "Third item", "labels":["baz"] }] }; const filtered = {"items": secondObj["items"].filter(item=>item.labels.filter(val =>firstArr.includes(val)).length)} console.log(filtered)

Edit: As @ggorlen stated, using Array#some is more efficient than using Array#includes for each search item.编辑:正如@ggorlen所说,对于每个搜索项,使用Array#some比使用Array#includes更有效。

 const firstArr = ['foo', 'bar']; const secondObj = { items: [ { name: 'First item', labels: ['foo'], }, { name: 'Second item', labels: ['foo', 'bar'], }, { name: 'Third item', labels: ['baz'], }, ], }; const filter = (o, arr) => ({ items: o.items.filter((item) => item.labels.some((label) => firstArr.indexOf(label) + 1) ), }); console.log(filter(secondObj, firstArr));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM