typescript-extended-linq
TypeScript icon, indicating that this package has built-in type declarations

4.1.0 • Public • Published

typescript-extended-linq

This is a library that is a direct translation of System.Linq from .NET and many additional functions from MoreLINQ.

Table of Contents

  1. Installation
  2. Why use this library?
  3. Basic Usage
  4. Documentation

Installation:

npm i typescript-extended-linq

You can optionally bind the Linq functions to native types (arrays, maps, sets, strings, etc). Binding to native types adds the functions to the type's prototype. Always be mindful when modifying a native type's prototype. While these functions will not affect native functionality, it cannot be guaranteed that it will not affect other frameworks if they also modify prototypes.

Add the following at the start of your program to bind to native types (the eslint disable is only needed if you use that eslint rule) Note, if adding the declarations to its own d.ts file, be sure to import IEnumerable and the Extension interfaces for IDEs to work right:

/* eslint-disable @typescript-eslint/no-empty-interface */
import { bindLinqToNativeTypes } from 'typescript-extended-linq';

declare global {
  interface Array<T> extends Omit<IEnumerable<T>, 'forEach' | 'toString' | 'toJSON' | symbol>, IArrayExtensions<T> {}
  interface Int8Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Int16Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Int32Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Uint8ClampedArray extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Uint16Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Uint32Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Float32Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Float64Array extends Omit<IEnumerable<number>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Map<K, V> extends Omit<IEnumerable<[K, V]>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface Set<T> extends Omit<IEnumerable<T>, 'forEach' | 'toString' | 'toJSON' | symbol> {}
  interface String
    extends Omit<IEnumerable<string>, 'endsWith' | 'startsWith' | 'split' | 'toString' | 'toJSON' | symbol> {}
}

bindLinqToNativeTypes();

You will then be able to see Linq methods on native types without needing to use the from() wrapper:

[1, 2, 3]
  .where(x => x > 1)
  .take(1)
  .toArray();

Any function that already existed on the native type (toString(), forEach() for example) will not be overridden and will continue to use the native function. Note that the call to bindLinqToNativeTypes must be done prior to using the functions on native types. This, for example, will not work:

foo.ts

export const foo = [1, 2, 3].where(x => x > 1).toArray();

index.ts

import { bindLinqToNativeTypes } from 'typescript-extended-linq';
import { foo } from './foo';

bindLinqToNativeTypes();

console.log(foo);

This will not work because the import line is before the bind function is ran and when that file is imported, it tries to use the 'where' function.

This, however, will work fine:

foo.ts

export function foo(): number[] {
  return [1, 2, 3].where(x => x > 1).toArray();
}

index.ts

import { bindLinqToNativeTypes } from 'typescript-extended-linq';
import { foo } from './foo';

bindLinqToNativeTypes();

console.log(foo());

Because the 'where' is not used until the foo function is invoked which is after the bind function is called.

If you only want to bind to certain types, you can pass in an optional object to do so (be sure to update the global type declarations):

import { bindLinqToNativeTypes } from 'typescript-extended-linq';

bindLinqToNativeTypes({ types: [Array] }); // Now only array will have new functions. Sets, Strings, Maps, etc will not.

You can also pass in optional functions to not bind to native types (once again, be sure to update the global type declarations):

import { bindLinqToNativeTypes } from 'typescript-extended-linq';

bindLinqToNativeTypes({ types: [Array], functionsToIgnore: ['aggregate'] }); // Only arrays will have new functions but it will not have aggregate.

Why use this library?

Additional Functionality

  • Native JavaScript/TypeScript provides many useful functions that are similar to LINQ (such as map, filter, reduce, etc). This library fills in the missing gaps with many functions that are not included in the native language such as joins, multi-level ordering, grouping, etc.

Additional Collections

Deferred Execution

TypeScript First

  • This library was written in Typescript so type definitions are included out of the box and are always up to date. The Typescript source code is included in the package so users can easily look at the implementation.
  • Documentation is also auto-generated on every release so they will always be up to date as well.

Basic Usage:

import { from } from 'typescript-extended-linq';

const items = [
  { id: 1, foo: 'a', bar: new Date('8/1/2021') },
  { id: 2, foo: 'a', bar: new Date('8/1/2021') },
  { id: 2, foo: 'b', bar: new Date('8/1/2021') },
  { id: 2, foo: 'a', bar: new Date('9/1/2021') },
  { id: 3, foo: 'a', bar: new Date('8/1/2021') },
  { id: 3, foo: 'b', bar: new Date('8/1/2021') }
];

const query = from(items)
  .where(item => item.id % 2 === 0)
  .orderBy(item => item.id)
  .thenBy(item => item.foo)
  .thenBy(item => item.bar);

/**
 * Will log:
 * [
 *  { id: 2, foo: 'a', bar: 2021-08-01T07:00:00.000Z },
 *  { id: 2, foo: 'a', bar: 2021-09-01T07:00:00.000Z },
 *  { id: 2, foo: 'b', bar: 2021-08-01T07:00:00.000Z }
 * ]
 */
console.log(query.toArray());

const sumOfIds = query.sum(item => item.id);

// Will log 6
console.log(sumOfIds);

const distinct = query.distinctBy(item => item.id).toArray();

// Will log [ { id: 2, foo: 'a', bar: 2021-08-01T07:00:00.000Z } ]
console.log(distinct);

Each function also can be used directly by passing in the source iterable as the first argument:

import { join } from 'typescript-extended-linq';

type Person = { name: string };
type Pet = { name: string; owner: Person };

const magnus: Person = { name: 'Magnus' };
const terry: Person = { name: 'Terry' };
const adam: Person = { name: 'Adam' };
const john: Person = { name: 'John' };

const barley: Pet = { name: 'Barley', owner: terry };
const boots: Pet = { name: 'Boots', owner: terry };
const whiskers: Pet = { name: 'Whiskers', owner: adam };
const daisy: Pet = { name: 'Daisy', owner: magnus };
const scratchy: Pet = { name: 'Scratchy', owner: { name: 'Bob' } };

const people = from([magnus, terry, adam, john]);
const pets = from([barley, boots, whiskers, daisy, scratchy]);

const result = join(
  people,
  pets,
  person => person,
  pet => pet.owner,
  (person, pet) => ({ ownerName: person.name, pet: pet.name })
).toArray();

/**
 * Will log:
 * [
 *   { ownerName: 'Magnus', pet: 'Daisy' },
 *   { ownerName: 'Terry', pet: 'Barley' },
 *   { ownerName: 'Terry', pet: 'Boots' },
 *   { ownerName: 'Adam', pet: 'Whiskers' }
 * ]
 */
console.log(result);

Documentation

Please see full documentation here.

aggregate

Applies an accumulator function over a sequence.

all

Determines whether all elements of a sequence satisfy a condition.

any

Determines whether any element of a sequence exists or satisfies a condition.

append

Appends a value to the end of the sequence.

asEnumerable

Returns the input as an IEnumerable.

assert

Tests a sequence with a given predicate. An error will be thrown if any element fails the sequence.

atLeast

Determines whether or not the number of elements in the sequence is greater than or equal to the given integer.

atMost

Determines whether or not the number of elements in the sequence is lesser than or equal to the given integer.

average

Computes the average of a sequence of numeric values.

chunk

Split the elements of a sequence into chunks of size at most chunkSize.

concatenate

Concatenates two sequences.

contains

Determines whether a sequence contains a specified element.

count

Returns the number of elements in a sequence.

defaultIfEmpty

Returns the elements of the specified sequence or the specified value in a singleton collection if the sequence is empty.

distinct

Returns distinct elements from a sequence.

distinctBy

Returns distinct elements from a sequence according to a specified key selector function.

elementAt

Returns the element at a specified index in a sequence. A negative index can be used to get element starting from the end.

elementAtOrDefault

Returns the element at a specified index in a sequence or null if the index is out of range. A negative index can be used to get element starting from the end.

endsWith

Determines whether the end of the first sequence is equivalent to the second sequence.

except

Produces the set difference of two sequences.

exceptBy

Produces the set difference of two sequences according to a specified key selector function.

first

Returns the first element in a sequence. Throws if sequence contains no elements.

firstOrDefault

Returns the first element in a sequence. Returns null if sequence contains no elements

flatten

Returns a new IEnumerable with all sub-iterable elements concatenated into it recursively up to the specified depth.

forEach

Iterates the sequence and calls an action on each element.

fullJoinHeterogeneous

Performs a full outer join on two heterogeneous sequences.

fullJoinHomogeneous

Performs a full outer join on two homogeneous sequences.

groupBy

Groups the elements of a sequence according to a specified key selector function.

groupJoin

Correlates the elements of two sequences based on key equality, and groups the results.

innerJoin

Performs an inner join by correlating the elements of two sequences based on matching keys.

intersect

Produces the set intersection of two sequences.

intersectBy

Produces the set intersection of two sequences according to a specified key selector function.

interweave

Interweaves multiple sequences.

last

Returns the last element of a sequence.

lastOrDefault

Returns the last element of a sequence, or null if the sequence contains no elements.

leftJoinHeterogeneous

Performs a left outer join on two heterogeneous sequences. Additional arguments specify key selection functions and result projection functions.

leftJoinHomogeneous

Performs a left outer join on two homogeneous sequences. Additional arguments specify key selection functions and result projection functions.

max

Returns the maximum value in a sequence of values.

maxBy

Returns the maximum value in a generic sequence according to a specified key selector function.

min

Returns the min value in a sequence of values.

minBy

Returns the min value in a generic sequence according to a specified key selector function.

ofType

Filters the elements of an IEnumerable based on a specified type.

order

Sorts the elements of a sequence in ascending order.

orderDescending

Sorts the elements of a sequence in descending order.

orderBy

Sorts the elements of a sequence in ascending order.

orderByDescending

Sorts the elements of a sequence in descending order.

pipe

Executes the given action on each element in the source sequence and yields it.

prepend

Adds a value to the beginning of the sequence.

quantile

Computes the quantile of a sequence.

reverseImmutable

Inverts the order of the elements in a sequence.

rightJoinHeterogeneous

Performs a right outer join on two heterogeneous sequences.

rightJoinHomogeneous

Performs a right outer join on two homogeneous sequences.

select

Projects each element of a sequence into a new form.

selectMany

Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.

sequenceEqual

Determines whether two sequences are equal by comparing the elements.

shuffle

Returns a new IEnumerable of the input sequence in random order.

single

Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.

singleOrDefault

Returns a single, specific element of a sequence, or null if that element is not found.

skip

Bypasses a specified number of elements in a sequence and then returns the remaining elements.

skipLast

Returns a new enumerable collection that contains the elements from source with the last count elements of the source collection omitted.

skipWhile

Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements.

split

Splits the source sequence by a separator.

startsWith

Determines whether the beginning of the first sequence is equivalent to the second sequence.

sum

Computes the sum of a sequence of numeric values.

take

Returns a specified number of contiguous elements from the start of a sequence.

takeEvery

Returns every N-th element of a sequence.

takeLast

Returns a new enumerable collection that contains the last count elements from source.

takeWhile

Returns elements from a sequence as long as a specified condition is true, and then skips the remaining elements.

thenBy

Performs a subsequent ordering of the elements in a sequence in ascending order.

thenByDescending

Performs a subsequent ordering of the elements in a sequence in descending order.

to

Creates a new instance of the passed in ctor with the Iterable as input.

toArray

Converts the source sequence into an array.

toMap

Creates a Map<TKey, TValue> from an IEnumerable according to specified key selector.

toObject

Returns an object with keys selected by keySelector and values of TSource.

toSet

Creates a Set from an IEnumerable.

union

Produces the set union of two sequences.

unionBy

Produces the set union of two sequences according to a specified key selector function.

where

Filters a sequence of values based on a predicate.

xor

Produces the symmetric difference of two sequences.

xorBy

Produces the symmetric difference of two sequences according to a specified key selector function.

zip

Produces a sequence of tuples with elements from the two specified sequences.

Dependents (0)

Package Sidebar

Install

npm i typescript-extended-linq

Weekly Downloads

0

Version

4.1.0

License

MIT

Unpacked Size

1.23 MB

Total Files

603

Last publish

Collaborators

  • rob893