Есть ли альтернативы методу filter у массива объектов JS

Есть примерно такой массив объектов:

const arr = [
  { flag: "Y", status: "Активна", name: "a" },
  { flag: "N", status: "Активна", name: "b" },
  { flag: "Y", status: "Отмена", name: "c" },
  { flag: "N", status: "Закрыта", name: "d" },
  { flag: "Y", status: "Закрыта", name: "e" },
];
  1. Нужно получить два массива, в первый попадают значения, которые одновременно имеют flag === "Y" и status === "Активна", а второй - все остальные значение, которые ОДНОВРЕМЕННО flag !== "Y" и status !== "Активна".
    То есть, если flag === "Y", то status === "Отмена" или "Закрыта". И наоборот status === "Активна", то flag === "N"

    Я делаю через фильтр

    arr.filter(task => task.flag === "Y" && task.status === "Активна")
    
    arr.filter(task => !(task.flag === "Y" && task.status === "Активна"))
    

    Вопрос: Какие еще есть варианты получить два отдельных массива, может быть еще более простые или фильтр тут хорош (и чем ? )

  2. Хочу разобраться, до конца не совсем пойму - почему результат этого выражения

    arr.filter(task => (task.flag !== "Y") && (task.status !== "Активна"))  
    

    отличается от

    arr.filter(task => !(task.flag === "Y" && task.status === "Активна"))
    

Ответы (1 шт):

Автор решения: yar85

Альтернативы двум проходам методом filter

  • Заполнение массивов в процедурном цикле:

const arr = [
  { flag: "Y", status: "Активна", name: "a" },
  { flag: "N", status: "Активна", name: "b" },
  { flag: "Y", status: "Отмена", name: "c" },
  { flag: "N", status: "Закрыта", name: "d" },
  { flag: "Y", status: "Закрыта", name: "e" },
];

const foo = [],
      bar = [];
for (const itm of arr) {
  if ((itm.flag === 'Y') && (itm.status === 'Активна'))
    foo.push(itm);
  else if ((itm.flag !== 'Y') && (itm.status !== 'Активна'))
    bar.push(itm);
}

console.log('foo:', foo, '\n', 'bar:', bar);


  • Деструктурирующее присваивание результата reduce (редьюс в двумерный массив):

const arr = [
  { flag: "Y", status: "Активна", name: "a" },
  { flag: "N", status: "Активна", name: "b" },
  { flag: "Y", status: "Отмена", name: "c" },
  { flag: "N", status: "Закрыта", name: "d" },
  { flag: "Y", status: "Закрыта", name: "e" },
];

const [foo, bar] = arr.reduce((rslt, itm) => {
  if ((itm.flag === 'Y') && (itm.status === 'Активна'))
    rslt[0].push(itm);
  else if ((itm.flag !== 'Y') && (itm.status !== 'Активна'))
    rslt[1].push(itm);
  return rslt;
}, [[], []]);

console.log('foo:', foo, '\n', 'bar:', bar);


Так как задачей определены свои условия для попадания в каждый из массивов - требуется выполнять две проверки.
Если бы во второй массив действительно попадали "все остальные значения", то есть безусловно (что задача исключает, наличием условий для второго массива) - то можно было бы обойтись без второй проверки: используя else или третий блок тернарного оператора.

→ Ссылка