Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add itertools-ts to TypeScript and JavaScript sections #1395

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

Conversation

Smoren
Copy link

@Smoren Smoren commented Mar 3, 2024

itertools-ts · npm Coverage Status Build and test

Extended itertools port for TypeScript and JavaScript. Provides a huge set of functions for working with iterable collections (including async ones).

Loop Iteration Tools Example

import { multi } from 'itertools-ts';

for (const [letter, number] of multi.zip(['a', 'b'], [1, 2])) {
  console.log(`${letter}${number}`);  // a1, b2
}

// Async example
for await (const [letter, number] of multi.zipAsync(['a', 'b'].map((x) => Promise.resolve(x)), [1, 2].map((x) => Promise.resolve(x)))) {
  console.log(`${letter}${number}`);  // a1, b2
}

Stream Iteration Tools Example

import { Stream, AsyncStream } from 'itertools-ts';

const result1 = Stream.of([1, 1, 2, 2, 3, 4, 5])
  .distinct()             // [1, 2, 3, 4, 5]
  .map((x) => x**2)       // [1, 4, 9, 16, 25]
  .filter((x) => x < 10)  // [1, 4, 9]
  .toSum();               // 14

// Async example
const result2 = await AsyncStream.of([1, 1, 2, 2, 3, 4, 5].map((x) => Promise.resolve(x)))
  .distinct()             // [1, 2, 3, 4, 5]
  .map((x) => x**2)       // [1, 4, 9, 16, 25]
  .filter((x) => x < 10)  // [1, 4, 9]
  .toSum();               // 14

Pipe Iteration Tools Example

import { createPipe } from 'itertools-ts';

const pipe = createPipe(
  set.distinct<number>,
  (input) => single.map(input, (x) => x**2),
  (input) => single.filter(input, (x) => x < 10),
  reduce.toSum,
);
const result1 = pipe([1, 1, 2, 2, 3, 4, 5]); // 14
const result2 = pipe([1, 1, 1, 2, 2, 2]);    // 5

// Async example
const asyncPipe = createPipe(
  set.distinctAsync<number>,
  (input) => single.mapAsync(input, (x) => x**2),
  (input) => single.filterAsync(input, (x) => x < 10),
  reduce.toSumAsync,
);
const result3 = await asyncPipe([1, 1, 2, 2, 3, 4, 5].map((x) => Promise.resolve(x))); // 14
const result4 = await asyncPipe([1, 1, 1, 2, 2, 2].map((x) => Promise.resolve(x)));    // 5

// Another way to create pipes
const anotherPipe = createPipe()
  .add(set.distinct<number>)
  .add((input) => single.map(input, (x) => x**2))
  .add((input) => single.filter(input, (x) => x < 10))
  .add(reduce.toSum);

const result5 = anotherPipe([1, 1, 2, 2, 3, 4, 5]); // 14
const result6 = anotherPipe([1, 1, 1, 2, 2, 2]);    // 5

All functions work on iterable collections and iterators:

  • Array
  • Set
  • Map
  • String
  • Generator
  • Iterable
  • Iterator

Every function have an analog with "Async"-suffixed name for working with async iterable and iterators (e.g. zip and zipAsync):

  • AsyncIterable
  • AsyncIterator

If an asynchronous function takes other functions as input, they can also be asynchronous.

Stream and Async Stream

Streams provide a fluent interface to transform arrays and iterables (sync or async) through a pipeline of operations.

Streams are made up of:

  1. One stream source factory method to create the stream.
  2. Zero or more stream operators that transform the stream to a new stream.
  3. Terminal operation of either:
    • Stream terminal operation to transform the stream to a value or data structure.
      const result1 = Stream.of([1, 1, 2, 2, 3, 4, 5])
        .distinct()             // [1, 2, 3, 4, 5]
        .map((x) => x**2)       // [1, 4, 9, 16, 25]
        .filter((x) => x < 10)  // [1, 4, 9]
        .toSum();               // 14
      
      // Async example
      const result2 = await AsyncStream.of([1, 1, 2, 2, 3, 4, 5].map((x) => Promise.resolve(x)))
        .distinct()             // [1, 2, 3, 4, 5]
        .map((x) => x**2)       // [1, 4, 9, 16, 25]
        .filter((x) => x < 10)  // [1, 4, 9]
        .toSum();               // 14
    • The stream is iterated via a for loop.
      const result1 = Stream.of([1, 1, 2, 2, 3, 4, 5])
        .distinct()             // [1, 2, 3, 4, 5]
        .map((x) => x**2)       // [1, 4, 9, 16, 25]
        .filter((x) => x < 10); // [1, 4, 9]
      
      for (const item of result1) {
        // 1, 4, 9
      }
      
      // Async example
      const result2 = AsyncStream.of([1, 1, 2, 2, 3, 4, 5].map((x) => Promise.resolve(x)))
        .distinct()             // [1, 2, 3, 4, 5]
        .map((x) => x**2)       // [1, 4, 9, 16, 25]
        .filter((x) => x < 10); // [1, 4, 9]
      
      for await (const item of result2) {
        // 1, 4, 9
      }

Copy link
Collaborator

@sammyhori sammyhori left a comment

Choose a reason for hiding this comment

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

Repo is mostly inactive, one update 3 weeks ago but only a few commits this year.

@sammyhori
Copy link
Collaborator

Going to close this for now due to worries about inactivity, feel free to reopen this if the repo becomes more active

@sammyhori sammyhori closed this Oct 19, 2024
@Smoren
Copy link
Author

Smoren commented Jan 25, 2025

@sammyhori Please reopen my PR because the repo is more active now. Thanks!

@sammyhori sammyhori reopened this Jan 27, 2025
Copy link
Collaborator

@sammyhori sammyhori left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution.
This pull request looks okay to me, there is only 1 beginner friendly issue and the repo has become slightly activate again recently - through the owner of the repo (and this pull request).

I have requested a change, feel free to commit it or discuss it with me if you would like.

data.json Outdated Show resolved Hide resolved
Co-authored-by: Sammy Hori <[email protected]>
@Smoren
Copy link
Author

Smoren commented Jan 28, 2025

Thank you @sammyhori for your feedback! I've commited you change request.

There is indeed only one issue in the project right now, but it includes many tasks for implementing various functions, and it will be updated over time.

I also have plans to add several useful functions to the set category myself in the near future, so the repository will remain active.

@Smoren Smoren requested a review from sammyhori January 30, 2025 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants