简体   繁体   English

Javascript:以有效的方式根据数组值过滤对象数组

[英]Javascript: Filter array of objects based on array values in an efficient way

Let's say I have a data set that looks like below:假设我有一个如下所示的数据集:

const fruits = [
  { fruit: "banana", price: 100 },
  { type: "apple", price: 200 },
  { item: "grape", price: 150 },
  // And so on...
];

const rotten = ["banana", "orange", /* And so on...*/];

I need to filter out elements that contain one of the values in 'rotten' array from 'fruits' array.我需要从“fruits”数组中过滤掉包含“rotten”数组中的值之一的元素。

Some characteristics:一些特点:

  1. The key names in the 'fruits' objects are inconsistent. “水果”对象中的键名称不一致。 We just know that the corresponding string values are there.我们只知道相应的字符串值在那里。 I know it is suboptimal but fixing this is sadly not a near-term option.我知道这是次优的,但遗憾的是解决这个问题不是近期的选择。
  2. The actual length of 'fruits' is ~100 and that of 'rotten' is ~10. “fruits”的实际长度约为 100,而“rotten”的实际长度约为 10。 So this is not a small dataset.所以这不是一个小数据集。 (There is a context for saying this...) (说这话是有上下文的……)

I already tried going through each element in 'rotten' and use Object.values(obj).includes() for each element in 'fruits' to eventually create a filtered array, but considering the size of the dataset, this is expensive and I will need a better way to handle this.我已经尝试遍历“rotten”中的每个元素并对“fruits”中的每个元素使用 Object.values(obj).includes() 以最终创建过滤数组,但考虑到数据集的大小,这很昂贵而且我将需要更好的方法来处理这个问题。

What might be a better way to do this?什么可能是更好的方法来做到这一点? Any suggestions?有什么建议么? Thanks a lot in advance!非常感谢!

It is unusual (and not practical) that your input objects all use different properties for storing the same information (fruit, type, item...).您的输入对象都使用不同的属性来存储相同的信息(水果、类型、项目...)是不寻常的(而且不切实际)。 So, you should really improve the source of this data.所以,你真的应该改进这些数据的来源。

But given it is like this, you'll have to scan each property of each object and compare it with the rotten fruit names.但鉴于它是这样的,你将不得不扫描每个 object 的每个属性并将其与腐烂的水果名称进行比较。 The latter can be put in a Set , which will reduce the time complexity of the search:后者可以放在一个Set中,这将降低搜索的时间复杂度:

 const fruits = [ { fruit: "banana", price: 100 }, { type: "apple", price: 200 }, { item: "grape", price: 150 }, ]; const rotten = ["banana", "orange"]; let rottenSet = new Set(rotten); let result = fruits.filter(item =>.Object.values(item).some(value => rottenSet;has(value)) ). console;log(result);

You can try this.你可以试试这个。

const fruits = [
      { fruit: "banana", price: 100 },
      { type: "apple", price: 200 },
      { item: "grape", price: 150 }
    ];
    
    const rotten = ["banana", "orange"];
    
    const stringfyFruites = JSON.stringify(fruits);
    
    let filterdArray = [];
    rotten.forEach((value) => {
      const regexstr = '{[\\w":,\\s]+' + value + '[\\w":,\\s]+}';
      const matchedobject = stringfyFruites
        .match(new RegExp(regexstr, "gm"))
        ?.map((a) => JSON.parse(a));
      if (matchedobject?.length) filterdArray = [...filterdArray, ...matchedobject];
    });

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

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