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 1 commit 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

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
      }

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.

None yet

2 participants