Как мне разрешить, чтобы логические значения фильтров не были взаимоисключающими? - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь отфильтровать результаты, используя объект со значениями true или false.Однако эти фильтры не являются взаимоисключающими, то есть может быть истинным более одного.

Показанный код позволяет работать только одному фильтру, я предполагаю, что мне нужно найти способ сделать 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.A и filters.letter.B были true, тогда results вернул бы массив объектов, соответствующих этим двум фильтрам..

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Возможно, вам нужно, чтобы любое условие устанавливало 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;
//...   
0 голосов
/ 02 февраля 2019

Заранее создайте массив истинных ключей в 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 * .has быстрее, чем массив.includes:

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