Фильтр с условием «

#javascript #arrays #filter

#javascript #массивы #Фильтр

Вопрос:

Итак, люди, у меня есть 3 флажка:

                     <label>
                        <input type="checkbox" value="Java" id="check-java" class="check-java filled-in" 
                         />
                        <span>Java</span>
                    </label>
                    amp;nbsp;
                    <label>
                        <input type="checkbox" value="JavaScript" id="check-javascript" class="check-javascript filled-in" />
                        <span>JavaScript</span>
                    </label>
                    amp;nbsp;
                    <label>
                        <input type="checkbox" value="Python" id="check-python" class="check-python filled-in"
                             />
                        <span>Python</span>
                    </label>
  

И когда пользователь устанавливает эти флажки, я перехватываю его в EventListener `:

 const checkBoxes = document.querySelectorAll('input[type=checkbox]');
checkBoxes.forEach((box) => {
    return box.addEventListener('change', filterByCheckBox)
});
  

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

 function filterByCheckBox(e) {
                const checkOption = e.target.value;
                if (devsFiltered.length > 0) {
                    const filtered  = devsFiltered
                    .filter(item => item.programmingLanguages
                        .every(lang => lang.language == checkOption));
                         mapUsers(filtered)
                }
        }
  

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

1. (1) Ваша filtered переменная является локальной переменной, поэтому ваша filterByCheckBox функция не имеет никакого эффекта. (2) Мне непонятно, что вы подразумеваете под «фильтровать только в том случае, если […]». Не могли бы вы привести пример, когда поведение вашего кода не соответствует тому, что вы хотите, и объяснить, каким должно быть поведение в этом случае?

2. Извините за радио, я пытаюсь немного упростить код для публикации здесь, и я не замечаю, что я не изменил addeventlistener, а «отфильтрованный» я передаю функции в качестве параметра и там обрабатываю данные и передаю загрузку на веб-страницу.

3. Таким образом, вы должны были бы получить все отмеченные флажки, а не только текущий

4. @epascarello нравится массив выбранных флажков и один цикл for для прохождения через массив и проверки в .every()?

Ответ №1:

Вам нужно получить все выбранные элементы и посмотреть, все ли отмеченные элементы находятся в массиве.

 var people = [
 { name: "w", codes : ['a', 'b'] },
 { name: "x", codes : ['a', 'c'] },
 { name: "y", codes : ['a', 'b'] },
 { name: "z", codes : ['b','c'] }
];

var form = document.querySelector("form");
form.addEventListener("change", function() {
  // get all the checked checkboxes
  const selections = document.querySelectorAll('[type="checkbox"]:checked');
  // get all their values
  const values = selections amp;amp; [...selections].map(({
    value
  }) => value);
  // filter the list to make sure all the values are in the object
  const filtered = values ?
    people.filter(({
        codes
      }) =>
      values.every(code => codes.includes(code))) : people;
      
  // Just to display something
  console.log(filtered.map(f => f.name).join(","));
});  
 <form id="form">
  <label for="a">A</label><input type="checkbox" id="a" value="a" />
  <label for="b">B</label><input type="checkbox" id="b" value="b" />
  <label for="c">C</label><input type="checkbox" id="c" value="c" />
</form>  

в формате, который немного более удобочитаем

Вам нужно получить все выбранные элементы и посмотреть, все ли отмеченные элементы находятся в массиве.

 var people = [
 { name: "w", codes : ['a', 'b'] },
 { name: "x", codes : ['a', 'c'] },
 { name: "y", codes : ['a', 'b'] },
 { name: "z", codes : ['b','c'] }
];

var form = document.querySelector("form");
form.addEventListener("change", function() {

  let filtered = people;

  const selections = document.querySelectorAll('[type="checkbox"]:checked');
  
  if (selections) {
    const values = [...selections].map(x => x.value);
    filtered = people.filter(person =>
      values.every(code => 
        person.codes.includes(code)
      )
    )
  }
      
  // Just to display something
  console.log(filtered.map(f => f.name).join(","));
});  
 <form id="form">
  <label for="a">A</label><input type="checkbox" id="a" value="a" />
  <label for="b">B</label><input type="checkbox" id="b" value="b" />
  <label for="c">C</label><input type="checkbox" id="c" value="c" />
</form>  

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

1. Итак… Я попытался реализовать ваш код на моем: function () { const selections = document . querySelectorAll(‘[type=»checkbox»]:проверено’); if (selections) { const values = […selections].map(x => x.value); const filtered = devsFiltered .filter(item => values .every(code => item.programmingLanguages.включает(код) )); console.log(фильтруется); } }) Но на самом деле, когда проходит мимо «filtered», возвращается пустой массив, я проверил devsFiltered и заполнен.

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