Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What is the Python itertools cycle equivalent in Javascript?

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading