Array.filter работает только один раз

#javascript #arrays

#javascript #массивы

Вопрос:

моя проблема в том, что у меня есть эта функция:

 function filterByCheckBox(e) {
   if (e.target.checked == true) {
       const checkOption = e.target.value;
       const div = document.getElementById('peoples');
       if (devsFiltered != "") {
           const filtered = devsFiltered.filter(item => {
               for (let x = 0; x < item.programmingLanguages.length; x  ) {
                   return item.programmingLanguages[x].language == checkOption;
               }
           });
           div.innerHTML = ""
           devsFiltered = filtered;
           mapUsers(filtered);
       }
   }
}
const checkBoxes = document.querySelectorAll('input[type=checkbox]');
checkBoxes.forEach(box => {
   return box.addEventListener('change', filterByCheckBox)
})

  

По сути, я фильтрую массив «devsFiltered» в соответствии со значением, указанным флажком, где указаны 3 возможных варианта: Java, JavaScript или Python, а в devsFiltered у меня есть массив информации и подмассив под названием «programmingLanguages», где содержатся языки для фильтрации, поэтому проблема в том,когда я устанавливаю флажок в первый раз, работает нормально и возвращает отфильтрованный массив, но если я попробую еще раз, когда функция выполняет devsFiltered.filter(), он просто возвращает пустой массив.
Есть идеи?

То, что я проверил: devsFiltered после первого фильтра не пуст.

Комментарии:

1. Если вы можете вызвать filter on devsFiltered , то, предположительно, это массив, что означает, что вы не должны сравнивать его с пустой строкой. Вы имеете в виду devsFiltered.length > 0 ?

2. У вас есть for цикл с необусловленным return в нем, что означает, что это больше не цикл.

3. Ваша цель здесь — попытаться извлечь, какие языки были проверены, а затем отфильтровать какой-либо другой список на основе этих выборов? Если это так, похоже, вам просто нужно сократить свой входящий список до language свойств каждого. Сложно оценить этот код, потому что вы не даете никакого образца ввода или желаемого результата.

4. @tadman спасибо за наблюдение, я меняю его, но не решает проблему.

5. Здесь много проблем, например, много слоев, и я не уверен, что смогу решить их все одним махом.

Ответ №1:

        const filtered = devsFiltered.filter(item => {
           for (let x = 0; x < item.programmingLanguages.length; x  ) {
               return item.programmingLanguages[x].language == checkOption;
           }
       });
  

Ваш for цикл всегда возвращается, когда попадает на первый язык программирования, что означает, что вы фильтруете программистов, чей первый язык программирования соответствует тому, который вы проверили, а не тех, у кого есть какой-либо соответствующий язык программирования. Если вы проверяете другой язык программирования, то вы фильтруете программистов, чей первый язык программирования соответствует обоим значениям флажка.

Рассмотрите возможность использования .some() вместо цикла:

        const filtered = devsFiltered
          .filter(item => item.programmingLanguages
              .some(lang => lang.language == checkOption));
  

Комментарии:

1. Большое вам спасибо! решил проблему, я застрял на этом часами.