Отфильтровать вложенный массив для определенного значения

У меня есть такой простой массив:

const test = [{
  test: 1,
  key: [{
    yes: true,
    no: null
  },{
    yes: true,
    no: null
  },{
    yes: false,
    no: null
  }]
},
{
  test: true,
  key: [{
    yes: true,
    no: null
  }]
},
{
  test: null,
  key: [{
    yes: null,
    no: null
  }]
}
];

И я хочу вернуть массив, который будет включать только те элементы, для которых test является правдивым (например, 1). А массив key внутри test будет включать только объекты с истинным значением для key.yes.

Итак, ожидаемый результат:

[
   {
     test: 1,
     key: [{yes: true, no: null},{yes: true, no: null}]
   },
   {
     test: true,
     key: [{yes: true, no: null}]
   }
];

Я попытался добиться этого с помощью такого простого фильтра:

const filtered = test.filter(obj => obj.test && obj.key.filter(item => item.yes).length > 0)

но это также возвращает значения массива key, которые являются false.

Есть идеи, почему?

вы хотите новый массив с новым массивом ключей или изменить старый?

Nina Scholz 31.10.2018 13:55

@NinaScholz Новый массив отлично подходит, поэтому я попытался использовать .filter

wasddd_ 31.10.2018 13:57
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
208
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам также придется отфильтровать каждый отдельный массив key.

// array where `test` is truthy
const filtered = test.filter(({ test }) => !!test);

// array where sub-arrays are filterd
const final = filtered.map(({ key }) => key.filter(({ yes }) => !!yes));
Ответ принят как подходящий

Вам нужно получить новый внешний массив и новые внутренние массивы, потому что внешняя фильтрация не меняет внутренние массивы. Если вы измените внутренний массив и отфильтруете внешний массив, вы измените данные.

Для получения независимого результата вы можете проверить test и, если правда, отфильтровать key и получить новый объект для набора результатов.

var test = [{ test: 1, key: [{ yes: true, no: null }, { yes: true, no: null }, { yes: false, no: null }] }, { test: true, key: [{ yes: true, no: null }] }, { test: null, key: [{ yes: null, no: null }] }],
    result = test.reduce((r, { test, key }) => {
        if (test) {
            r.push({ test, key: key.filter(({ yes }) => yes) });
        }
        return r;
    }, []);

console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Вы должны сначала отфильтровать основной массив, а затем переназначить его на новый поддиапазон фильтрации, например:

const filtered = test
   .filter(obj => obj.test && obj.key.some(item => item.yes))
   .map(d => {d.test, key: d.key.filter(item => item.yes));

Или, возможно, отфильтруйте массив по ключу. Да через мгновение:

const filtered = test
   .filter(obj => obj.test)
   .map(d => {d.test, key = d.key.filter(item => item.yes))
   .filter(s => s.key);

Другие вопросы по теме