JSPM

  • Created
  • Published
  • Downloads 3355
  • Score
    100M100P100Q119837F
  • License MIT

LINQ ported to TypeScript

Package Exports

  • linq-to-typescript

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (linq-to-typescript) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

LINQ To TypeScript

  • Implementation of LINQ for TypeScript
  • Targets TypeScript 2.8 and ES 2016
await Enumerable
    .from([bing, google, quackQuackGo])
    .asParallel()
    .selectAsync(downloadHtml)
    .select(getTitle)
    .toArray()
Release InDev

Getting Started

npm i linq-to-typescript

npm version bundle size

tsconfig.json

"compilerOptions": {
    "target": "es2016",
    "lib": [
      "dom",
      "es2016",
      "esnext.asynciterable"
    ],
}
  • The strict TS option is recommended.
  • Library is dependent on core-js for implementation of Symbol.asyncIterator

Using the Library

With Wrappers

// 0. Import Module
import { ArrayEnumerable, Enumerable, AsyncEnumerable, ParallelEnumerable } from "linq-to-typescript"

// To Use With Wrappers
const evenNumbers = Enumerable.from([1, 2, 3, 4, 5, 6, 7, 8, 9]).where((x) => x % 2 === 0).toArray()

Without Wrappers

// 0. Import Module
import { Enumerable, AsyncEnumerable, ParallelEnumerable, initializeLinq } from "linq-to-typescript"
// 1. Declare that the JS types implement the IEnumerable interface
declare global {
    interface Array<T> extends IEnumerable<T> {
        concat(items: IEnumerable<T>): IEnumerable<T>;
        concat(...items: Array<ReadonlyArray<T>>): ArrayEnumerable<T>;
        concat(...items: Array<T | ReadonlyArray<T>>): ArrayEnumerable<T>;    
    }
    interface Uint8Array extends IEnumerable<number> { }
    interface Uint8ClampedArray extends IEnumerable<number> { }
    interface Uint16Array extends IEnumerable<number> { }
    interface Uint32Array extends IEnumerable<number> { }
    interface Int8Array extends IEnumerable<number> { }
    interface Int16Array extends IEnumerable<number> { }
    interface Int32Array extends IEnumerable<number> { }
    interface Float32Array extends IEnumerable<number> { }
    interface Float64Array extends IEnumerable<number> { }
    interface Map<K, V> extends IEnumerable<[K, V]> { }
    interface Set<T> extends IEnumerable<T> { }
    interface String extends IEnumerable<string> { }
}
// 2. Bind Linq Functions to Array and Map
initializeLinq()
// 3. Use without a wrapper type
const evenNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9].where((x) => x % 2 === 0).toArray()

Examples

Please refer to EXAMPLES.md

API

LinqToTypeScript implements the functionality of the IEnumerable interface

  • IEnumerable, IAsyncEnumerable, and IParallelEnumerable interfaces are based on,
  • IEnumerable<T> Interface
  • Some changes made due to conflics with existing method names
  • Some changes made due to limitations of JavaScript

IEnumerable

  • Inspired by LINQ API Surface
  • Has Async methods that return Promise or IAsyncEnumerable
  • Implements Iterable<T> interface

IAsyncEnumerable

  • Inspired by LINQ API Surface
  • Has Async methods that return Promise or IAsyncEnumerable
  • For asynchronous iteration
  • Implements AsyncIterable<T> interface

IParallelEnumerable

  • Inspired by LINQ API Surface
  • Has Async methods that return Promise or IParallelEnumerable
  • For asynchronous iteration in parallel (where possible)
  • Implements AsyncIterable<T> interface.

Shared Instance Methods

Method Async* Tests Coverage Notes
aggregate No Sync
all Yes Sync, Async
any Yes Sync, Async
average Yes Sync, Async
concat No Sync
contains Yes Sync, Async
count Yes Sync, Async
distinct Yes Sync, Async
elementAt No Sync
elementAtOrDefault No Sync
except Yes Sync, Async
first Yes Sync, Async
firstOrDefault Yes Sync, Async
each Yes Sync, Async From List<T>.ForEach
groupBy Yes Sync, Async
groupByWithSel No Sync
intersect Yes Sync, Async
joinByKey No Sync
last Yes Sync, Async
lastOrDefault Yes Sync, Async
max Yes Sync, Async
min Yes Sync, Async
ofType No Sync
orderBy Yes Sync, Async
orderByDescending Yes Sync, Async
reverse No Sync
select Yes Sync, Async
selectMany Yes Sync, Async
sequenceEquals Yes Sync, Async
single Yes Sync, Async
singleOrDefault Yes Sync, Async
skip No Sync
skipWhile Yes Sync, Async
sum Yes Sync, Async
take No Sync
takeWhile Yes Sync, Async
toArray No Sync
toMap Yes Sync, Async Equivalent to ToDictionary
toSet No Sync Equivalent to ToHashSet
union Yes Sync
where Yes Sync, Async
zip Yes Sync, Async

* Async methods take an async function

Static Methods

Method Enumerable Async Parallel Tests Coverage
empty Yes Yes Yes Test
enumerateObject Yes Yes No Test
flatten Yes Yes Yes Test
fromEvent No Yes No Test
range Yes Yes No Test
repeat Yes Yes Yes Test

TypeDoc Documentation

Refer to https://arogozine.github.io/linqtotypescript/

Design

Binding new APIs to Array Types

JavaScript doesn't have extension methods like in C#, therefore we extend the class itself with new methods. Call initializeLinq to bind library functions to default Array methods,

The following collections support IEnumerable,

  • Array
  • Map
  • Set
  • String
  • Int8Array
  • Int16Array
  • Int32Array
  • Uint8Array
  • Uint8ClampedArray
  • Uint16Array
  • Uint32Array
  • Float32Array
  • Float64Array

Using Wrappers

Wrappers are safer as they won't interfere with other libraries.

// To Create an IEnumerable<T>
Enumerable.from(iterableIteratorOrArray)
// To Create an IAsyncEnumerable<T>
AsyncEnumerable.from(asyncIterableIteratorOrPromiseArray)
// To Create an IParallelEnumerable<T>
ParallelEnumerable.from(arrayOfPromises)

The root classes are

  • Enumerable
  • AsyncEnumerable
  • ParallelEnumerable

Collections simply call the static methods defined on these base types.

F.A.Q.

Q I am getting a Cannot find module 'core-js/modules/es7.symbol.async-iterator'

A Ensure you have core-js NPM package installed.

Q Why did you create this?

A For fun and to gain understanding of TypeScript and Node Package Manager.

Q Why not target ES5?

A ES5 doesn't have iterators and generators which this library relies on to mimic the lazy nature of IEnumerable. You are free to target ES5 instead.

Q How does this compare to other LINQ libraries?

A They are more mature, but not made targeting latest ECMAScript features.

Q Why should I use this instead of lodash or something similar?

A

  • TypeScript first. Libraries which target JavaScript first do additional type checking which can have a negative impact on performance.
  • This library uses iterators and generators. These are new language features which have no support in legacy browsers like IE11.

Q Which browsers are supported?

A Firefox, Chrome, and Edge. IE is not supported.

Q Can I contribute?

A Please do!