What is the Python itertools cycle equivalent in Javascript?

Question:

I could not find an equivalent function of Python cycle in itertools:

from itertools import cycle
g = cycle(('a','b'))
next(g) # a
next(g) # b
next(g) # a
# etc. etc.

in Javascript.

The goal is to create an infinite cycle in an array of values. I guess I could use a Javascript generator but I was wondering if there is any built-in function.

Asked By: G M

||

Answers:

There is no built in functionality for this. With that said, it is easy to make a function that accepts any number of arguments and cycles through them:

function* cycle(...items) {
  while(true)
    yield* items;
}


const gen = cycle("a", "b");

console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

This uses yield* to delegate to the iterator of the array items, effectively yield* items; is a shorter version of

for (const item of items)
  yield item;

Alternatively, it can accept an array and continually cycle through its contents

function* cycle(items) {
  while(true)
    yield* items;
}


const gen = cycle(["a", "b"]);

console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);

If it has to support any iterables passed in, it will have to maintain a chache of the first iteration, so it can repeat the further cycles. I have shown an implementation of this in this answer of mine. Here is the implementation:

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.log(iterator.next().value) // prints value1
console.log(iterator.next().value) // prints value2
console.log(iterator.next().value) // prints value1
console.log(iterator.next().value) // prints value2
console.log(iterator.next().value) // prints value1
console.log(iterator.next().value) // prints value2


There is a proposal called Iterator helpers which aims to add tools similar to itertools and, in general, ease the use of iterators. The proposal is currently in stage 2 out of 4 in the approval process.

Answered By: VLAZ
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.