‚̧npm promulgates marsupials
    Have ideas to improve npm?Join in the discussion! ¬Ľ

    itiriri
    TypeScript icon, indicating that this package has built-in type declarations

    2.0.1¬†‚Äʬ†Public¬†‚Äʬ†Published

    itiriri

    Build Status Coverage Status NPM Version license

    A library built for ES6 iteration protocol.

    function* numbers() {
      let n = 1;
     
      while (true) {
        yield n++;
      }
    }
     
    const s = itiriri(numbers()).map(n => 1 / (n * n)).take(1000).sum();
    console.log(Math.sqrt(6 * s));
    // 3.1406380562059946

    itiriri provides similar functions as JavaScript arrays: filter, slice, map, reduce, every, some etc. and more. The functions are optimized for ES6 iterators and can be chained to perform simple but powerful manipulations over iterables.

    Installation

    Using npm

    $ npm install 'itiriri' --save

    Importing

    import itiriri from 'itiriri';

    Support

    The itiriri library can be used with any ES6 compatible runtime.

    Usage

    itiriri can be used with a build-it type like array, Map, Set, a generator function or a custom iterable.

    import itiriri from 'itiriri';
     
    const values = [2, 0, 4, 8];
     
    const s = itiriri(values).map(n => n / 2).reverse();
    console.log(s.toString()); // prints: 4,2,0,1
     
    // prints: 4 2 0 1
    for (const n of s) {
      console.log(n)
    }
     
    console.log(s.sum()); // prints: 7

    Deferred execution

    JavaScript's array methods like filter, slice and others that return an array create a shallow copy for the result and are executed once called.

    itiriri functions that return iterables are not executed unless chained with a function that reduces a value or transforms to a built-in type. The iterable source is iterated only once.

    Let's see what happens in the below example.

    import itiriri from 'itiriri';
     
    function* fibonacci() {
      let [a, b] = [0, 1];
     
      while (true) {
        yield a;
        [a, b] = [b, a + b];
      }
    }
     
    // Finding first 3 Fibonacci numbers that contain 42
    const result = itiriri(fibonacci())
      .filter(x => x.toString().indexOf('42') !== -1)
      .take(3);
     
    for (const e of result) {
      console.log(e);
    }
     
    // outputs: 514229, 267914296, 7778742049

    Step by step:

    1. result is assigned to a itiriri. At this point numbers array is not iterated, the execution is deferred until the result is being iterated.

    2. filter method creates an iterator to pipe only numbers passing the predicate. filter does not buffer elements and only pipes them one-by-one to take as it is iterated.

    3. take pipes only first three elements as it is iterated and breaks.

    4. for...of instruction starts iteration and requests elements one at a time.

    Due to deferred execution, most of the functions that don't need entire sequence of elements to build an iterator (like filter, map, concat etc.) can be used with infinite iterables (like Fibonacci in the above example). These functions are also optimized to pass elements through and do not buffer them resulting in a more optimized memory usage.

    Functions like sort, reverse, shuffle etc. that require entire sequence of elements in order to build an iterator expect to receive a finite iterable.

    Benchmarks

    Using itiriri is considerable faster than using array methods when processing large inputs.

    In filter-map-slice example arrays of different size are used to filter and map a result of 100 elements:

    Array size (N) array itiriri
    1000 111,611 ops/sec ¬Ī9.63% (86 runs) 44,213 ops/sec ¬Ī1.92% (88 runs)
    5000 18,507 ops/sec ¬Ī0.67% (90 runs) 42,103 ops/sec ¬Ī2.63% (84 runs)
    10000 8,655 ops/sec ¬Ī0.70% (91 runs) 42,803 ops/sec ¬Ī2.20% (86 runs)
    50000 1,640 ops/sec ¬Ī0.79% (88 runs) 43,446 ops/sec ¬Ī2.17% (88 runs)
    100000 848 ops/sec ¬Ī0.93% (87 runs) 43,137 ops/sec ¬Ī2.15% (87 runs)
    200000 46.38 ops/sec ¬Ī0.74% (59 runs) 42,445 ops/sec ¬Ī2.48% (90 runs)

    map-filter-slice

    Using array methods performance drops significantly for large inputs due to creation of intermediary states for filter and map.
    Using itiriri iteration always stops after 100 elements are found, therefore the size of the input doesn't affect the performance.

    More benchmarks can be found in /benchmark.

    Running Tests

    $ npm install
    $ npm test

    Bundling

    If you want to use itiriri in the browser, there is a gulp task that creates a minified file:

    $ npm install
    $ gulp bundle
    // creates itiriri.min.js file in the root folder

    Once you include the itiriri.min.js file on your page, you can use it as:

    <script src="itiriri.min.js"></script>
    <!-- ... -->
    <script>
        // source can be an array or an Iterable
        const source = [1, 2, 3];
        console.log(itiriri(source).sum());
    </script> 

    Complete list of methods

    average

    Returns the average value.

    Syntax

    average(): number;
    average(selector: (element: T, index: number) => number): number;

    Parameters

    • selector - (optional) a value transformer that accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns a number that is used for average value calculation

    For a sequence with no elements returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri([41, 42, 43]).average()  // returns 42
    itiriri([{value: 1}, {value: 2}]).average(elem => elem.value) // returns 1.5
    itiriri([]).average() // returns undefined

    concat

    Concatenates a sequence with another one.

    Syntax

    concat(other: Iterable<T>): IterableQuery<T>;
    concat(other: T): IterableQuery<T>;

    Parameters

    • other - (required) a sequence or a value to be concatenated

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).concat([4, 5]).toArray()  // returns [1, 2, 3, 4, 5]

    concat is a deferred method and is executed only when the result sequence is iterated.

    distinct

    Returns a sequence of unique elements.

    Syntax

    distinct(): IterableQuery<T>;
    distinct<S>(selector: (element: T) => S): IterableQuery<T>;

    Parameters

    • selector - (optional) a function to get element's value for comparison. Accepts one argument:
      • element - current element
      • returns a value to be used for comparison

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 42, 3, 4, 1]).distinct().toArray();  // returns [1, 42, 3, 4]
    itiriri([{value: 1}, {value: 2}, {value: 1}])
      .distinct(elem => elem.value)
      .toArray(); // returns [{value: 1}, {value: 2}]

    distinct is a deferred method and is executed only when the result sequence is iterated.

    entries

    Returns a sequence of key/value pair for each element and its index.

    Syntax

    entries(): IterableQuery<[number, T]>;

    Example

    import itiriri from 'itiriri';
     
    itiriri(['Alice', 'Bob', 'David']).entries().toArray();
    // returns [[0, 'Alice'], [1, 'Bob'], [2, 'David']]

    entries is a deferred method and is executed only when the result sequence is iterated.

    every

    Tests whether all the elements pass the predicate.

    Syntax

    every(predicate: (element: T, index: number) => boolean): boolean;

    Parameters

    • predicate - (required) function to test for each element
      • element - the current element
      • index - the index of the current element
      • returns true or false

    Example

    import itiriri from 'itiriri';
     
    itiriri([2, 4, 9]).every(elem => elem > 0); // returns true
    itiriri([7, 23, 3]).every(elem => elem % 3 === 0); // returns false

    exclude

    Returns a sequence of elements not contained in a given sequence.

    Syntax

    exclude<S>(others: Iterable<T>): IterableQuery<T>;
    exclude<S>(others: Iterable<T>, selector: (element: T) => S): IterableQuery<T>;

    Parameters

    • others - (required) a sequence of elements to be excluded
    • selector - (optional) a function to get element's value for comparison, accepts one argument:
      • element - current element
      • returns a value to be used for comparison

    Example

    import itiriri from 'itiriri';
     
    itiriri([2, 0, 1, 8, 2]).exclude([0, 1]).toArray(); // returns [2, 8, 2]
    itiriri([{id: 1}, {id: 2}])
      .exclude([{id: 2}, elem => elem.id])
      .toArray(); // returns [{id: 1}]

    exclude is a deferred method and is executed only when the result sequence is iterated.

    fill

    Returns a sequence filled from a start index to an end index with a static value. The end index is not included.

    Syntax

    fill(value: T): IterableQuery<T>;
    fill(value: T, start: number): IterableQuery<T>;
    fill(value: T, start: number, end: number): IterableQuery<T>;

    Parameters

    • value - (required) value to fill
    • start - (optional) start index, defaults to 0
    • end - (optional) end index, defaults to sequence length

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).fill([7]).toArray(); // returns [7, 7, 7, 7, 7]
    itiriri([1, 2, 3, 4, 5]).fill([7, 3]).toArray(); // returns [1, 2, 3, 7, 7]
    itiriri([1, 2, 3, 4, 5]).fill([7, 1, 3]).toArray(); // returns [1, 7, 7, 4, 5]

    fill is a deferred method and is executed only when the result sequence is iterated.

    filter

    Returns a sequence of elements that pass the predicate.

    Syntax

    filter(predicate: (element: T, index: number) => boolean): IterableQuery<T>;

    Parameters

    • predicate - (required) function to test for each element that accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true or false

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).filter(elem => elem < 3).toArray(); // returns [1, 2]
    itiriri([1, 2, 3]).filter(elem > 10).toArray(); // returns []

    filter is a deferred method and is executed only when the result sequence is iterated.

    find

    Finds the first element that satisfies the specified predicate.

    Syntax

    find(predicate: (element: T, index: number) => boolean): T;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true if element satisfies the predicate, false otherwise

    If no element satisfies the predicate, returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).find(elem => elem % 2 === 0); // returns 2
    itiriri([1, 2, 3]).find(elem > 10); // returns undefined

    findIndex

    Finds the first index at which a given element satisfies the specified predicate.

    Syntax

    findIndex(predicate: (element: T, index: number) => boolean): number;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true if element satisfies the predicate, false otherwise

    If no element satisfies the predicate, returns -1.

    Example

    import itiriri from 'itiriri';
     
    itiriri([7, 12, 15]).findIndex(elem => elem > 10 && elem < 15); // returns 1
    itiriri([1, 2, 3]).findIndex(elem > 10); // returns -1

    findLast

    Finds the last element that satisfies the specified predicate.

    Syntax

    findLast(predicate: (element: T, index: number) => boolean): T;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true if element satisfies the predicate, false otherwise

    If no element satisfies the predicate, returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri([11, 7, 21]).findLast(elem => elem > 10); // returns 21
    itiriri([1, 2, 3]).findLast(elem > 10); // returns undefined

    findLastIndex

    Finds the last index at which a given element satisfies the specified predicate.

    Syntax

    findLastIndex(predicate: (element: T, index: number) => boolean): number;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true if element satisfies the predicate, false otherwise

    If not present, returns -1.

    Example

    import itiriri from 'itiriri';
     
    itiriri([11, 7, 21]).findLastIndex(elem => elem > 10); // returns 2
    itiriri([1, 2, 3]).findLastIndex(elem > 10); // returns -1

    first

    Returns the first element in a sequence.

    Syntax

    first(): T;

    For an empty sequence returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c']).first(); // returns 'a'
    itiriri([]).first(); // returns undefined

    flat

    Returns a sequence with all sub-sequences concatenated.

    Syntax

    flat<S>(selector: (element: T, index: number) => Iterable<S>): IterableQuery<S>;

    Parameters

    • selector - (required) a transformation function to map each element to a sequence, accepts two arguments
      • element - the current element
      • index - the index of the current element
      • returns an iterable

    Example

    import itiriri from 'itiriri';
     
    itiriri([{value: [1, 2], {values: [7, 9]}]).flat(elem => elem.value).toArray();
    // returns [1, 2, 7, 9]

    flat is a deferred method and is executed only when the result sequence is iterated.

    forEach

    Runs through every element and applies a given function.

    Syntax

    forEach(action: (element: T, index: number) => void): void;

    Parameters

    • action - (required) function to apply on each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).forEach(elem => console.log(elem));
    // 1
    // 2
    // 3

    groupBy

    Groups elements by a given key, optionally applying a transformation over each element.

    Syntax

    groupBy<K>(
      keySelector: (element: T, index: number) => K): IterableQuery<[K, IterableQuery<T>]>;
     
    groupBy<K, E>(
      keySelector: (element: T, index: number) => K,
      valueSelector: (element: T, index: number) => E): IterableQuery<[K, IterableQuery<E>]>;

    Parameters

    • keySelector - (required) function that provides element's group key, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns the group key of current element
    • valueSelector - (optional) function to transform values, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns a transformation of current element

    Example

    import itiriri from 'itiriri';
     
    const students = [
      {name: 'Alice', gender: 'female'},
      {name: 'Bob', gender: 'male'},
      {name: 'David', gender: 'male'},
    ];
     
    itiriri(students).groupBy(elem => elem.gender, elem => elem.name).toArray();
    // [['female', ['Alice']], ['male', ['Bob', 'David']]]

    groupBy is a deferred method and is executed only when the result sequence is iterated.

    groupJoin

    Returns a sequence of correlated elements where each element from the current sequence is matched with zero or more elements from the other sequence.

    Syntax

    groupJoin<TKey, TRight, TResult>(
        other: Iterable<TRight>,
        leftKeySelector: (element: T, index: number) => TKey,
        rightKeySelector: (element: TRight, index: number) => TKey,
        joinSelector: (left: T, right: TRight[]) => TResult,
      ): IterableQuery<TResult>;

    Parameters

    • other - (required) sequence to join
    • leftKeySelector - (required) function that provides the key of each element from the source sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • rightKeySelector - (required) function that provides the key of each element from joined sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • joinSelector - (required) a transformation function to apply on each joined element with group, accepts two arguments:
      • left - element from the original source
      • right - array of elements from the joined source that have the same key as left element's key

    The joinSelector function is called on each element from the source sequence and the array of matched elements from the joined sequence.
    When an element from the source sequence doesn't match with any of the elements from the joined sequence, the joinSelector function will be called with an empty array.

    Example

    import itiriri from 'itiriri';
     
    const books = [
      {title: 'Clean code', categoryId: 1 },
      {title: 'Code complete', categoryId: 1},
      {title: 'Scrum', categoryId: 2},
    ];
     
    const categories = [
      {id: 1, name: 'CS'},
      {id: 2, name: 'Agile'},
    ];
     
    itiriri(categories).groupJoin(
      books,
      category => category.id,
      book => book.categoryId,
      (category, books) => ({ category: category.name, books: books.map(b => b.title) })
    ).toArray();
    // [
    //   {category: 'CS', books: ['Clean code', 'Code complete']},
    //   {category: 'Agile', books: ['Scrum']}
    // ]

    groupJoin is a deferred method and is executed only when the result sequence is iterated.

    includes

    Determines whether the sequence includes a certain element.

    Syntax

    includes(element: T): boolean;
    includes(element: T, fromIndex: number): boolean;

    Parameters

    • element - (required) the element to search for
    • fromIndex - (optional) starting index, defaults to 0

    includes uses triple equals === to compare elements.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).includes(2); // returns true
    itiriri([1, 2, 3]).includes(0); // returns false

    indexOf

    Returns the first (zero-based) index at which a given element can be found.

    Syntax

    indexOf(element: T): number;
    indexOf(element: T, fromIndex: number): number;

    Parameters

    • element - (required) the element to search for
    • fromIndex - (optional) starting index, defaults to 0

    When an element is not found, returns -1.
    indexOf uses triple equals === to compare elements.

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c']).indexOf('c'); // returns 2
    itiriri(['a', 'b', 'c']).indexOf('x'); // returns -1

    intersect

    Returns a set intersection with a given sequence.

    Syntax

    intersect(others: Iterable<T>): IterableQuery<T>;
    intersect<S>(other: Iterable<T>, selector: (element: T) => S): IterableQuery<T>;

    Parameters

    • other - (required) the sequence to intersect with
    • selector - (optional) a value transformer function to be used for comparisons, accepts one argument:
      • element - the current element
      • returns a value used for comparisons

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]]).intersect([2, 3, 4]).toArray(); // returns [2, 3]
    itiriri([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'})
      .intersect([{id: 3, name: 'David'}, {id: 1, name: 'Alice'}], elem => elem.id)
      .toArray(); // returns [{id: 1, name: 'Alice'}]

    intersect is a deferred method and is executed only when the result sequence is iterated.

    join

    Returns a sequence of correlated elements transformation that match a given key.

    Syntax

    join<TKey, TRight, TResult>(
        other: Iterable<TRight>,
        leftKeySelector: (element: T, index: number) => TKey,
        rightKeySelector: (element: TRight, index: number) => TKey,
        joinSelector: (left: T, right: TRight) => TResult,
      ): IterableQuery<TResult>;

    Parameters

    • other - (required) sequence to join
    • leftKeySelector - (required) function that provides the key of each element from source sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • rightKeySelector - (required) function that provides the key of each element from joined sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • joinSelector - (required) a transformation function to apply on each matched tuple, accepts two arguments:
      • left - element from the source sequence
      • right - element from the joined sequence
      • returns a new result

    The join method works as an sql inner join.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3])
      .join([2, 3, 4], n => n, n => n, (a, b) => `${a}-${b}`)
      .toArray();
    // returns ['2-2', '3-3']
     
    itiriri([{countryId: 1, code: '+1'}, {countryId: 2, code: '+44'}]])
      .join(
        [{ id: 1, country: 'US' }, {id: 3, country: 'MD'}],
        left => left.countryId,
        right => right.id,
        (left, right) => ({country: right.country, code: left.code}))
      .toArray();
    // returns [{country: 'US', code: '+1'}]

    join is a deferred method and is executed only when the result sequence is iterated.

    keys

    Returns a sequence of keys for each index in the source sequence.

    Syntax

    keys(): IterableQuery<number>;

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c']).keys().toArray(); // returns [0, 1, 2]

    keys is a deferred method and is executed only when the result sequence is iterated.

    last

    Returns the last element in a sequence.

    Syntax

    last(): T;

    For an empty sequence returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c']).last(); // returns 'c'
    itiriri([]).last(); // returns undefined

    lastIndexOf

    Returns the last index at which a given element can be found.

    Syntax

    lastIndexOf(element: T): number;
    lastIndexOf(element: T, fromIndex: number): number;

    Parameters

    • element - (required) the element to search for
    • fromIndex - (optional) starting index, defaults to 0

    When an element is not found, returns -1.
    lastIndexOf uses triple equals === to compare elements.

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'c', 'c']).lastIndexOf('c'); // returns 2
    itiriri(['a', 'b', 'c']).lastIndexOf('x'); // returns -1

    leftJoin

    Returns a sequence of correlated elements transformation that match a given key.

    Syntax

    leftJoin<TKey, TRight, TResult>(
        other: Iterable<TRight>,
        leftKeySelector: (element: T, index: number) => TKey,
        rightKeySelector: (element: TRight, index: number) => TKey,
        joinSelector: (left: T, right?: TRight) => TResult,
      ): IterableQuery<TResult>;

    Parameters

    • other - (required) sequence to join
    • leftKeySelector - (required) function that provides the key of each element from source sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • rightKeySelector - (required) function that provides the key of each element from joined sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • joinSelector - (required) a transformation function to apply on each matched tuple, accepts two arguments:
      • left - element from the source sequence
      • right - element from the joined sequence, or undefined if no match was found
      • returns element's key

    The leftJoin method works as an sql left join. When an element from the left sequence doesn't match with any of the elements from the right sequence, the joinSelector function is called with an undefined right value.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3])
      .leftJoin([2, 3, 4, 2], n => n, n => n, (a, b) => `${a}-${b || '#'}`)
      .toArray();
    // returns ['1-#', '2-2', '2-2', '3-3']
     
    itiriri([{book: 'History', owner: 3}, {book: 'Math', owner: 2}, {book: 'Art'}]])
      .leftJoin(
        [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}, {id: 3, name: 'Eve'}],
        left => left.owner,
        right => right.id,
        (left, right) => ({book: left.book, owner: right && right.owner || '--'}))
      .toArray();
    // returns [
    //   {book: 'History', owner: 'Eve'},
    //   {book: 'Math', owner: 'Bob'},
    //   {book: 'Art', owner: '--'}]

    leftJoin is a deferred method and is executed only when the result sequence is iterated.

    length

    Returns the number of elements in a sequence.

    Syntax

    length(): number;
    length(predicate: (element: T, index: number) => boolean): number;

    Parameters

    • predicate - (optional) a function to count only the elements that match the predicate, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true or false

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).length();  // returns 5
    itiriri([1, 2, 3, 4, 5]).length(elem => elem > 2);  // returns 3

    map

    Returns a sequence of transformed values.

    Syntax

    map<S>(selector: (element: T, index: number) => S): IterableQuery<S>;

    Parameters

    • selector - (required) a value transformer function to apply to each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns a new value

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).map(elem => elem * 10).toArray(); // returns [10, 20, 30]

    map is a deferred method and is executed only when the result sequence is iterated.

    max

    Returns the maximum element in a sequence.

    Syntax

    max(): T;
    max(compareFn: (a: T, b: T) => number): T;

    Parameters

    • compareFn - (optional) a comparer function that compares two elements from a sequence and returns:
      • -1 when a is less than b
      • 1 when a is greater b
      • 0 when a equals to b

    If sequence is empty, returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).max(); // returns 3
    itiriri([]).max(); // returns undefined
    itiriri([7, 3, 11, 5]).max((a, b) => (1 / a) - (1 / b)); // returns 3

    min

    Returns the minimum element in a sequence.

    Syntax

    min(): number;
    min(compareFn: (a: T, b: T) => number): T;

    Parameters

    • compareFn - (optional) a comparer function that compares two elements from a sequence and returns:
      • -1 when a is less than b
      • 1 when a is greater b
      • 0 when a equals to b

    If sequence is empty, returns undefined.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).min(); // returns 1
    itiriri([]).min(); // returns undefined
    itiriri([7, 3, 11, 5]).min((a, b) => (1 / a) - (1 / b)); // returns 11

    nth

    Returns the element at a specified index.

    Syntax

    nth(index: number): T;

    Parameters

    • index - (required) zero based index at which to get the element

    For a negative index returns the element from the end of the sequence.
    If index is out of the range, returns undefined .

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c', 'd']).nth(2)  // returns 'c'
    itiriri(['a', 'b', 'c', 'd']).nth(-1) // returns 'd'
    itiriri(['a', 'b', 'c', 'd']).nth(10) // returns undefined

    prepend

    Returns a sequence with given elements at the beginning.

    Syntax

    prepend(other: Iterable<T>): IterableQuery<T>;
    prepend(other: T): IterableQuery<T>;

    Parameters

    • other - (required) the sequence or element to be added at the beginning

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).prepend([9, 10]).toArray(); // returns [1, 2, 3, 9, 10]

    prepend is a deferred method and is executed only when the result sequence is iterated.

    reduce

    Applies a function against an accumulator and each element (from left to right) to reduce it to a single value.

    Syntax

    reduce(
        callback: (accumulator: T, current: T, index: number) => T,
      ): T;
     
    reduce<S>(
        callback: (accumulator: S, current: T, index: number) => S,
        initialValue: S,
      ): S;

    Parameters

    • callback - (required) function to execute on each element in the sequence, taking three arguments
      • accumulator the accumulator accumulates the callback's return values;
      • current the current element being processed;
      • currentIndex the index of the current element being processed;
    • initialValue - (optional) value to use as the first argument to the first call of the callback

    Calling reduce on an empty sequence without an initial value throws an error.

    Example

    import itiriri from 'itiriri';
     
    itiriri([ 1, 2, 42, 0 ]).reduce((acc, elem) => Math.max(acc, elem)); // returns 42
    itiriri([ 1, 2, 3 ]).reduce((acc, elem) => acc + elem, 10); // returns 16

    reduceRight

    Applies a function against an accumulator and each element (from right to left) to reduce it to a single value.

    Syntax

    reduceRight(
        callback: (accumulator: T, current: T, index: number) => T,
      ): T;
     
    reduceRight<S>(
        callback: (accumulator: S, current: T, index: number) => S,
        initialValue: S,
      ): S;

    Parameters

    • callback - (required) function to execute on each element in the sequence, taking three arguments
      • accumulator the accumulator accumulates the callback's return values;
      • current the current element being processed;
      • currentIndex the index of the current element being processed;
    • initialValue - (optional) value to use as the first argument to the first call of the callback

    Calling reduceRight on an empty sequence without an initial value throws an error.

    Example

    import itiriri from 'itiriri';
     
    itiriri([ 1, 2, 42, 0 ]).reduceRight((acc, elem) => Math.max(acc, elem)); // returns 42
    itiriri([ 1, 2, 3]).reduceRight((acc, elem) => acc.concat(elem), []); // returns [3, 2, 1]

    reverse

    Returns a sequence of elements in a reversed order.

    Syntax

    reverse(): IterableQuery<T>;

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).reverse().toArray(); // returns [3, 2, 1]

    reverse is a deferred method and is executed only when the result sequence is iterated.

    rightJoin

    Returns a sequence of correlated elements transformation that match a given key.

    Syntax

    rightJoin<TKey, TRight, TResult>(
        other: Iterable<TRight>,
        rightKeySelector: (element: TRight, index: number) => TKey,
        leftKeySelector: (element: T, index: number) => TKey,
        joinSelector: (right: TRight, left?: T) => TResult,
      ): IterableQuery<TResult>;

    Parameters

    • other - (required) sequence to join
    • rightKeySelector - (required) function that provides the key of each element from joined sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • leftKeySelector - (required) function that provides the key of each element from source sequence, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns element's key
    • joinSelector - (required) a transformation function to apply on each matched tuple, accepts two arguments:
      • right - element from the joined sequence
      • left - element from the source sequence, or undefined if no match found
      • returns new result

    The rightJoin method works as an sql right join. When an element from the right sequence doesn't match with any of the elements from the left sequence, the rightJoin function is called with an undefined left value.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3])
      .rightJoin([2, 3, 4, 2], n => n, n => n, (a, b) => `${a || '#'}-${b}`)
      .toArray();
    // returns ['2-2', '3-3', '#-4', '2-2']
     
    itiriri([{book: 'History', owner: 3}, {book: 'Math', owner: 2}]])
      .rightJoin(
        [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}, {id: 3, name: 'Eve'}],
        right => right.id,
        left => left.owner,
        (right, left) => ({student: right.name, book: left && left.book || '--'}))
      .toArray();
    // returns [
    //   {student: 'Alice', book: '--'},
    //   {student: 'Bob', book: 'Math'},
    //   {student: 'Eve', book: 'History'}]

    rightJoin is a deferred method and is executed only when the result sequence is iterated.

    shuffle

    Returns the sequence of elements in a random order.

    Syntax

    shuffle(): IterableQuery<T>;

    This method is implemented using Fisher‚ÄďYates algorithm for generating the random permutation. Math.rand() is used to generate random numbers.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).shuffle().toArray();
    // returns a random permutation of the same elements
    // like: [2, 5, 3, 1, 4]

    shuffle is a deferred method and is executed only when the result sequence is iterated.

    skip

    Skips the specified number of elements from the beginning of sequence and returns the remaining ones.

    Syntax

    skip(count: number): IterableQuery<T>;

    Parameters

    • count - (required) number of elements to skip

    When count is greater than actual number of elements, results in an empty sequence.
    Accepts also a negative count, in which case skips the elements from the end of the sequence.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).skip(2).toArray(); // [3, 4, 5]
    itiriri([1, 2, 3, 4, 5]).skip(10).toArray(); // []
    itiriri([1, 2, 3, 4, 5]).skip(-2).toArray(); // [1, 2, 3]

    skip is a deferred method and is executed only when the result sequence is iterated.

    skipWhile

    Skip elements while they satisfy the predicate.

    Syntax

    skipWhile<T>(predicate: (element: T, index: number) => boolean): IterableQuery<T>;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).skipWhile(() => true); // returns []
    itiriri([1, 2, 3]).skipWhile(() => false); // returns [1, 2, 3]
    itiriri([1, 2, 3]).skipWhile(e => e < 3); // returns [3]
    itiriri([1, 2, 3]).skipWhile(e => e % 2 === 0); // returns [1, 2, 3]

    skipWhile is a deferred method and is executed only when the result sequence is iterated.

    slice

    Returns a sequence that represents the range of elements from start to end.

    Syntax

    slice(start: number): IterableQuery<T>;
    slice(start: number, end: number): IterableQuery<T>;

    Parameters

    • start - (required) zero-based index at which to begin extraction
    • end - (optional) zero-based index before which to end extraction

    The end index is not included in the result.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 4, 5]).slice(1, 3).toArray(); // returns [2, 3]

    slice is a deferred method and is executed only when the result sequence is iterated.

    some

    Tests whether at least one element passes the predicate.

    Syntax

    some(predicate: (element: T, index: number) => boolean): boolean;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns true or false

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 42, 5]).some(elem => elem > 40); // returns true
    itiriri([1, 2, 3, 42, 5]).some(elem => elem < 0); // returns false

    sort

    Returns a sequence of sorted elements.

    Syntax

    sort(): IterableQuery<T>;
    sort(compareFn: (a: T, b: T) => number): IterableQuery<T>;

    Parameters

    • compareFn - (optional) a comparer function that compares two elements from a sequence and returns:
      • -1 when a is less than b
      • 1 when a is greater b
      • 0 when a equals to b

    This method fallbacks to native JavaScript array sort method.

    Example

    import itiriri from 'itiriri';
     
    itiriri([7, 9, 0, 4, 12]).sort().toArray(); // returns [0, 4, 7, 9, 12]
    itiriri([
      {score: 1, value: 'a'},
      {score: 0, value: 'b'},
      {score: 2, value: 'c'}])
      .sort((a, b)) => a.score - b.score);
    // returns [
    //  {score: 0, value: 'b'},
    //  {score: 1, value: 'a'},
    //  {score: 2, value: 'c'}]

    sort is a deferred method and is executed only when the result sequence is iterated.

    splice

    Returns a sequence that skips elements and/or adds new elements.

    Syntax

    splice(start: number, deleteCount: number, ...items: T[]): IterableQuery<T>;

    Parameters

    • start - (required) index at which to start changing the sequence
    • deleteCount - (optional) an integer indicating the number of original elements to skip
    • items - (optional) elements to add to the sequence

    Example

    import itiriri from 'itiriri';
     
    itiriri(['angel', 'clown', 'mandarin', 'sturgeon'])
      .splice(2, 0, 'drum').toArray();
    // returns ['angel', 'clown', 'drum', 'mandarin', 'sturgeon']
     
    itiriri(['angel', 'clown', 'drum', 'mandarin', 'sturgeon'])
      .splice(3, 1).toArray();
    // returns ['angel', 'clown', 'drum', 'sturgeon']

    splice is a deferred method and is executed only when the result sequence is iterated.

    sum

    Returns the sum of all elements.

    Syntax

    sum(): number;
    sum(selector: (element: T, index: number) => number): number;

    Parameters

    • selector - (optional) a value transformer function to apply to each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element
      • returns a value to be used for sum calculation

    Optionally, a function can be provided to apply a transformation and map each element to a value.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).sum(); // returns 6
    itiriri([{value: 1}, {value: 2}]).sum(elem => elem.value); // returns 3

    take

    Returns a specified number of elements from the beginning of sequence.

    Syntax

    take(count: number): IterableQuery<T>;

    Parameters

    • count - (required) number of elements to take

    If a negative count is specified, returns elements from the end of the sequence.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).take(2); // returns [1, 2]
    itiriri([1, 2, 3]).take(-2); // returns [2, 3]
    itiriri([1, 2, 3]).take(10); // returns [1, 2, 3]

    take is a deferred method and is executed only when the result sequence is iterated.

    takeWhile

    Returns elements while they satisfy the predicate.

    Syntax

    takeWhile<T>(predicate: (element: T, index: number) => boolean): IterableQuery<T>;

    Parameters

    • predicate - (required) function to test for each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).takeWhile(() => true); // returns [1, 2, 3]
    itiriri([1, 2, 3]).takeWhile(() => false); // returns []
    itiriri([1, 2, 3]).takeWhile(e => e < 3); // returns [1, 2]
    itiriri([1, 2, 3]).takeWhile(e => e % 2 === 0); // returns []

    takeWhile is a deferred method and is executed only when the result sequence is iterated.

    toArray

    Creates an array copy of the sequence.

    Syntax

    toArray(): T[];
    toArray<S>(selector: (element: T, index: number) => S): S[];

    Parameters

    • selector - (optional) a value transformer function to apply to each element

    When providing a selector function, creates an array of values returned by applying the function on each element.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).toArray(); // returns [1, 2, 3]
    itiriri([{value: 1}, {value: 2}]).toArray(elem => elem.value); // returns [1, 2]

    toGroups

    Creates a map of element groups by a given key.

    Syntax

    toGroups<M>(
      keySelector: (element: T, index: number) => M): Map<M, T[]>;
      
    toGroups<M, N>(
      keySelector: (element: T, index: number) => M,
      valueSelector: (element: T, index: number) => N): Map<M, N[]>;

    Parameters

    • keySelector - (required) a transformer function to apply to each element to get its key, accepts two arguments:
      • element - the current element
      • index - the index of the current element
    • valueSelector - (optional) a transformer function to apply to each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Method toGroups creates a JavaScript Map of key-value pairs where each key is the result from keySelector and value is an array of elements (or the result of applying valueSelector on each element) from the original sequence for which the key is the same.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 7, 14, 4, 9]).toGroups(elem => elem % 2 === 0);
    // returns Map {0 => [14, 4], 1 => [1, 7, 9]}
     
    itiriri([
        {name: 'Alice', gender: 'female'},
        {name: 'Bob', gender: 'male'},
        {name: 'David', gender: 'male'}
      ])
      .toGroups(elem => elem.gender, elem => elem.name);
    // returns Map {'female' => ['Alice'], 'male' => ['Bob', 'David']}

    toMap

    Creates a map of elements by a given key.

    Syntax

    toMap<M>(
        keySelector: (element: T, index: number) => M): Map<M, T>;
     
    toMap<M, N>(
        keySelector: (element: T, index: number) => M,
        valueSelector: (element: T, index: number) => N): Map<M, N>;

    Parameters

    • keySelector - (required) a transformer function to apply to each element to get its key, accepts two arguments:
      • element - the current element
      • index - the index of the current element
    • valueSelector - (optional) a transformer function to apply to each element, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Method toMap returns a JavaScript Map of key-value pairs where each key is the result from keySelector and value is the element (or the result of applying valueSelector on the element) that corresponds to the key.

    If the sequence contains two elements with the same key, method toMap throws an error.

    Example

    import itiriri from 'itiriri';
     
    itiriri(['a', 'b', 'c']).toMap(elem => elem.charCodeAt(0));
    // returns Map {97 => 'a', 98 => 'b', 99 => 'c'}
     
    itiriri(['a', 'b', 'c']).toMap(elem => elem.charCodeAt(0), elem => elem.toUpperCase());
    // returns Map {97 => 'A', 98 => 'B', 99 => 'C'}
     
    itiriri([1, 1]).toMap(elem => elem);
    // throws an Error

    toSet

    Creates a set of elements.

    Syntax

    toSet(): Set<T>;
    toSet<S>(selector: (element: T, index: number) => S): Set<S>;

    Parameters

    • selector - (optional) a transformer function to apply to each element to get its value, accepts two arguments:
      • element - the current element
      • index - the index of the current element

    Method toSet returns a JavaScript Set of the original elements in the sequence, or their transformation when a selector is provided.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3, 1, 3]).toSet(); // returns Set {1, 2, 3}
    itiriri([{value: 1}, {value: 2}, {value: 1}])
      .toSet(elem => elem.value); // returns Set {1, 2}

    toString

    Returns a string representing the specified sequence and its elements.

    Syntax

    toString(): string;

    Method toString calls .toString() function on each element and joins the result by ,.

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]).toString(); // returns 1,2,3
    itiriri([1, null, 3]).toString(); // returns 1,,3
    itiriri([{value: 1}, {value: 2}]).toString(); // returns [object Object],[object Object]

    union

    Returns a set union with a given sequence.

    Syntax

    union(other: Iterable<T>): IterableQuery<T>;
    union<S>(other: Iterable<T>, selector: (element: T) => S): IterableQuery<T>;

    Parameters

    • other - (required) the sequence to join with
    • selector - (optional) a value transformer function to be used for comparisons, accepts one argument:
      • element - the current element

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]]).union([2, 3, 4]).toArray(); // returns [1, 2, 3, 4]
     
    itiriri([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'})
      .union([{id: 3, name: 'David'}, {id: 1, name: 'Alice'}], elem => elem.id)
      .toArray();
    // returns [
    //  {id: 1, name: 'Alice'},
    //  {id: 2, name: 'Bob'},
    //  {id: 3, name: 'David'}]

    union is a deferred method and is executed only when the result sequence is iterated.

    values

    Returns a sequence of values for each index in the source sequence.

    Syntax

    values(): IterableQuery<T>;

    Example

    import itiriri from 'itiriri';
     
    itiriri([1, 2, 3]]).values().toArray(); // returns [1, 2, 3]

    values is a deferred method and is executed only when the result sequence is iterated.

    License

    MIT

    Install

    npm i itiriri

    DownloadsWeekly Downloads

    102

    Version

    2.0.1

    License

    MIT

    Unpacked Size

    176 kB

    Total Files

    143

    Last publish

    Collaborators

    • avatar
    • avatar
    • avatar
    • avatar