Можете ли вы использовать reduce () в списке узлов? - PullRequest
0 голосов
/ 02 августа 2020

Я подумал, что reduce может помочь мне решить с минимальным кодом простую проверку нодлиста, но я не мог выяснить, не могу ли я заставить его работать, или я пропустил какое-то ограничение reduce, например, «это не работает» t работать с нодлистом ».

Это то, что я пробовал до сих пор:

Html:

<input class="form-check-input typeOfRepetition" type="radio" id="r1">
<input class="form-check-input typeOfRepetition" type="radio" id="r2">
<input class="form-check-input typeOfRepetition" type="radio" id="r2">

JS

typeOfRepetition__all= document.querySelectorAll('.typeOfRepetition')

const reducer = (acc, currV) => acc + (currV.checked ? 1 : 0)
const choiceChecked = els.typeOfRepetition__all.reduce(reducer);

if (choiceChecked) {
   //...do some stuff
}

Я пробовал использовать метод сокращения с проверкой тернарного оператора внутри песочницы MDN , и он работал хорошо, то есть:

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + ( currentValue % 2 ? 1 : 0);

// 1 + 2 + 3 + 4 becomes 1 + 0 + 1 + 0 = 2
console.log(array1.reduce(reducer));

, но я не мог понять, почему это не применимо к моей первоначальной идее. forEach хорошо работает с этим списком узлов / массивом, поэтому я ожидал, что он будет работать нормально и с reduce.

Любая помощь будет принята с благодарностью.

Редактировать : Перед публикацией я попытался использовать Array.from() в нодлисте, полученном из querySelectorAll, и это дало мне немного больше: reduce работает, но вместо того, чтобы вычислять чистый числовой вывод (например, ноль или один ответ), он дает мне что-то вроде

console.log('choiceChecked:', choiceChecked)
// choiceChecked: [object HTMLInputElement]10
// or
// choiceChecked: [object HTMLInputElement]00

Может, мне стоит перестать писать код так поздно ночью: P

Ответы [ 2 ]

4 голосов
/ 02 августа 2020

Да, вам нужно будет использовать Array.from в списке узлов, чтобы использовать reduce на нем.

Причина, по которой вы получаете [object HTMLInputElement]10 от редуктора, заключается в том, что при первом запуске acc устанавливается на первый узел (а не на свойство checked первого узла). С этого момента он, кажется, пытается объединить 0 s и 1 s с этим узлом как строки . Первый узел, преобразованный в строку, - '[object HTMLInputElement]'. Затем он объединяется с двумя другими значениями '[object HTMLInputElement]10'.

Вам необходимо передать начальное значение 0 в reduce:

Array.from(typeOfRepetition__all).reduce(reducer, 0);

Таким образом, начальное значение acc будет 0, а не первым узлом. Также обратите внимание, что теперь он будет повторяться три раза, а не дважды.

Однако похоже, что вы просто пытаетесь подсчитать количество отмеченных переключателей определенного класса. Почему бы просто не сделать:

document.querySelectorAll('.typeOfRepetition:checked').length
1 голос
/ 02 августа 2020

просто сделай

const choiceChecked = [...document.querySelectorAll('.typeOfRepetition')]
                      .reduce((a,c)=>a+(c.checked?1:0),0 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...