Есть ли лучший способ узнать, достиг ли итератор своего последнего значения?

#javascript #iterator

#javascript #итератор

Вопрос:

Я могу сделать это:

 let iter = mySet.values();
var val = iter.next();
var next = iter.next();
while(val.value){
  if(!next.done){
    // do something that I want to do to the last element
  }
  val = next;
  next  = iter.next();
}
  

но переменная ‘next’ кажется неуклюжей. Есть ли лучший способ?

Когда я проверяю объект mySet, я вижу ключ [[Entries]] с массивом значений, но как мне получить к нему доступ?

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

1. Вы можете использовать цикл for..of, если вам не нужно знать индекс

2. Предлагает ли javascript этот iterator.hasNext() метод? Никогда не использовал его в javascript, но этот метод предлагается на других языках.

3. mySet.value(); Это набор? Если да, вы имеете в виду .values() ?

4. @zfrisch почему набор снижает производительность? Set.has() более производителен, чем Array . найти или Array.some или indexOf

5. @zfrisch только что выполнил быстрый поиск и нашел допустимый jsperf jsperf.com/array-indexof-vs-set-has

Ответ №1:

Вы могли бы использовать while(!next.done) , и вы хотите использовать только next() один раз за итерацию.

Чтобы выяснить, является ли это последним значением, сохраните значение в переменной, затем переназначите next , а затем проверьте done перед обработкой значения

 function* myGen(arr) {
  let i = -1;
  while (  i < arr.length) {
    yield arr[i] * 2;
  }
}

const it = myGen([1, 2, 3]);

let next = it.next();

while (!next.done) {
  const val = next.value;
  next = it.next();
  console.log('value:', val, ' is last = ', next.done);
}

console.log('done:', next.done)  

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

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

2. хорошо … простое исправление … проверьте next.done внутри цикла также после нового присваивания и сначала сохраните значение внутри цикла в переменной. Затем вы можете работать со значением после проверки done и до закрытия цикла

3. это экономит 1 строку из моего подхода; начальный var val = iter.next(); . Спасибо за улучшение. Но вы говорите, что в принципе мне все еще нужны 2 переменные, чтобы увидеть, когда я нахожусь на последнем элементе?

4. Кажется, вы вызывали next слишком много раз. И да …. не вижу способа обойти одну переменную для значения и одну для следующего объекта

5. на практике это происходит столько же раз, сколько и у вас.

Ответ №2:

Из документа Mozilla:

«… метод next(), который возвращает объект с двумя свойствами: value, следующее значение в последовательности; и done, что является true, если последнее значение в последовательности уже было использовано».

В вашем подходе нет ничего плохого.