Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat(collections/unstable): add cycle iterator utility #6386

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

EGAMAGZ
Copy link

@EGAMAGZ EGAMAGZ commented Feb 6, 2025

No description provided.

@EGAMAGZ EGAMAGZ requested a review from kt3k as a code owner February 6, 2025 05:29
@CLAassistant
Copy link

CLAassistant commented Feb 6, 2025

CLA assistant check
All committers have signed the CLA.

Copy link

codecov bot commented Feb 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.23%. Comparing base (3b75ee7) to head (c30b491).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6386   +/-   ##
=======================================
  Coverage   96.23%   96.23%           
=======================================
  Files         556      557    +1     
  Lines       42065    42080   +15     
  Branches     6371     6375    +4     
=======================================
+ Hits        40481    40496   +15     
  Misses       1544     1544           
  Partials       40       40           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kt3k kt3k changed the title feat(collections): add cycle iterator utility feat(collections/unstable): add cycle iterator utility Feb 7, 2025
@kt3k kt3k added the enhancement New feature or request label Feb 7, 2025
@kt3k
Copy link
Member

kt3k commented Feb 7, 2025

We have policy to accept new features as unstable features (see https://github.com/denoland/std/blob/main/.github/CONTRIBUTING.md#new-features-in-stable-packages-version--100). Can you prefix the files with unstable_ and export it from the path ./unstable-cycle?

I'm not completely sure whether this is aligned with other APIs in std/collections. What do people think?

@BlackAsLight
Copy link
Contributor

It seems a bit weird to me for the function to ask for an Iterable when most iterables aren't 'cycle-able'. I think it would make more sense to ask for types that are guaranteed to be cycle-able, like Arrays and Maps.

The documentation mentions that if the iterable is empty then the code loops indefinitely. That is a memory leak. The code should check if its empty and either exit or throw an error.

export function* cycle<T>(iterable: Iterable<T>): Generator<T> {
  let isEmpty = false;
  while (true) {
    for (const x of iterable) {
      isEmpty = false;
      yield x;
    }
    if (isEmpty) break; // Or throw an error as iterable is not cycle-able.
    isEmpty = true;
  }
}

Comment on lines +32 to +41
let iterator = iterable[Symbol.iterator]();

while (true) {
const result = iterator.next();
if (result.done) {
iterator = iterable[Symbol.iterator]();
} else {
yield result.value;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use yield* this could be much more concise.

Suggested change
let iterator = iterable[Symbol.iterator]();
while (true) {
const result = iterator.next();
if (result.done) {
iterator = iterable[Symbol.iterator]();
} else {
yield result.value;
}
}
while (true) {
yield* iterable;
}

@timreichen
Copy link
Contributor

I wonder what some use cases are for these, I've never encountered one myself.
Seems like lodash doesn't provide any cycle() method, lodash-contrib does. So this function seems kinda niche.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
collections enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants