如何允许过滤器布尔值互斥?

时间:2019-02-02 09:12:48

标签: javascript arrays javascript-objects

我正在尝试使用一个值为truefalse的对象过滤结果。但是,这些过滤器不是互相排斥的,这意味着可以有多个过滤器。

所示的代码仅允许一个过滤器工作,我想我需要找出一种使showData动态化的方法,但我不太确定如何实现。

const filters = {
  letter: {
    A: false,
    B: false,
    C: false,
    D: false,
    E: false
  },
  number: {
    1: false,
    2: false,
    3: false,
    4: false
  },
  //...
};

const data = [
  {
    letter: "A",
    number: "1",
  },
  {
    letter: "B",
    number: "1",
  },
  {
    letter: "B",
    number: "2",
  },
  //...
],

const results = data.map((result, index) => {
  let showData = true;

  if (filters.letter.A) showData = result.letter === "A";
  if (filters.letter.B) showData = result.letter === "B";
  //...

  return (showData && result)
})}

预期输出的一个示例是,如果filters.letter.Afilters.letter.B均为true,则results将返回与这两个过滤器匹配的对象数组。

2 个答案:

答案 0 :(得分:2)

预先在filters.letter中构造一个真值密钥数组,然后可以基于当前迭代的当前卡的showCard是否包含在该数组中来设置.letter

const trueLetterKeys = Object.entries(filters.letter)
  .filter(([, val]) => val)
  .map(([key]) => key);
// ...
{data.map(({ letter }, index) => {
  const showCard = trueLetterKeys.includes(letter);
  // ...

没有多少项并不重要,但是要降低复杂性,可以使用Set的真实键而不是数组,因为Set的{​​{1}}比数组的.has更快:

.includes

答案 1 :(得分:0)

您可能需要任何条件都应设置showDara,但不能清除它。

简单的解决方案:

//...
if (letter.A) showData = showData || data.letter ===‘A’;
if (letter.B) showData = showData || data.letter ===‘B’;
//...

高级:

如果我猜对了您的数据,可以简化代码。

如果data.letter和data.number是合理的已净化值,不会干扰内置或继承的属性,则此代码将起作用:

//...
if(letter[data.letter] === true) showData = true;
if(number[data.number] === true) showData = true;
//...

更高级:

这段代码看起来更正确,但是有点复杂: (使用hasOwnProperty方法检查对象本身定义的属性,而不是从父对象继承的属性):

//...
if(letter.hasOwnProperty(data.letter) && letter[data.letter] === true) showData = true;
if(number.hasOwnProperty(data.number) && number[data.number] === true) showData = true;
//...