Как перезапустить итерацию с помощью метода Map.values()?

Я хочу перезапустить итерацию после того, как итератор достигнет состояния готовности. Просто посмотрите на пример:

const newMap = new Map<string, string>([
  ['key1', 'value1'],
  ['key2', 'value2']
]);

const iterator = newMap.values() // It can be newMap.entries()

iterator.next().value   // prints value1
iterator.next().value    //prints value2
iterator.next().value //prints undefined

Я просто хочу что-то вроде:

iterator.restart();
iterator.next().value // prints value1

Вы можете вызвать newMap.values() снова. Этого достаточно?

Nicholas Tower 18.03.2022 20:13

Я думал о том, чтобы просто поделиться одним свойством с другими службами и просто контролировать поток с его помощью, но, похоже, нет возможности перезапустить и повторно использовать это. может быть есть лучшие решения проблемы. Спасибо большое.

Mehdi Rahimi 18.03.2022 20:18
Поведение ключевого слова "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) для оценки ваших знаний,...
0
2
48
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вызовите .values (или любой другой способ) еще раз.

const newMap = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);

let iterator = newMap.values() // It can be newMap.entries()

console.info(iterator.next().value)   // prints value1
console.info(iterator.next().value)    //prints value2
console.info(iterator.next().value) //prints undefined

iterator = newMap.values()
console.info(iterator.next().value) // prints value1

Итераторы нельзя использовать повторно — вам придется создавать их заново каждый раз, когда вы хотите начать с самого начала.

Ответ принят как подходящий

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

function* repeat(iterable) {
  const cache = [];
  
  //lazily supply the values from the iterable while caching them
  for (const next of iterable) {
    cache.push(next);
    yield next;
  }
  
  //delegate to the cache at this point
  while(true)
    yield* cache;
}

const newMap = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);

const iterator = repeat(newMap.values()) // It can be newMap.entries()

console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2

В качестве альтернативы, если вы не хотите кэшировать, вы можете упростить реализацию repeat(), взяв функцию, которая дает вам итерацию. Каждый раз, когда вы вызываете его, вы получаете новый и делегируете его навсегда:

function* repeat(iterableSupplier) {
  //delegate to the value from the supplier
  while(true)
    yield* iterableSupplier();
}

const newMap = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);

const iterator = repeat(() => newMap.values()) // It can be newMap.entries()
//    give a function   ^^^^^

console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2

Подробнее о:

  • function* - функции генератора
  • yield* — делегирование другому итерируемому объекту
  • Итераторы и генераторы - больше по теме в целом

Вы можете создать свой собственный итератор, который при запросе снова вызывает newMap.values():

const newMap = new Map([
  ['key1', 'value1'],
  ['key2', 'value2']
]);

const myIterator = (() => {
  let currentIterator = newMap.values();
  
  return {
    next() {
      return currentIterator.next();
    },
    restart() {
      currentIterator = newMap.values();
    }
  }
})()
console.info(myIterator.next().value)   // prints value1
console.info(myIterator.next().value)    //prints value2
console.info(myIterator.next().value) //prints undefined

myIterator.restart();
console.info(myIterator.next().value) // prints value1

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