linqify
v1.2.2
Published
Javascript LINQ library based on C# LINQ
Downloads
13
Maintainers
Readme
LINQify
JavaScript library for lazy querying Arrays, Maps, Sets, and Strings based on LINQ (C#).
Provides List, Dictionary, HashSet, and Lookup with comparer for complex types.
Features:
- lazy evaluation with generator functions,
- extends native javascript Array, Set, Map, and String,
- C# LINQ naming convention, which does not collide with native methods (e.g. concat and join),
- includes typescript support in code editors.
Usage
Install
npm install linqify
Node CommonJS module
var {Enumerable, List, Dictionary, HashSet, EqualityComparers,
SortComparers, linqify} = require('linqify');
Node ES module
import {Enumerable, List, Dictionary, HashSet, EqualityComparers,
SortComparers, linqify} from 'linqify';
Browser
Always get the latest version
<script src="https://unpkg.com/linqify"></script>
Get the specific version
<script src="https://unpkg.com/[email protected]"></script>
Get the latest minor and patch version of specific major version
<script src="https://unpkg.com/linqify@1"></script>
Documentation, Blogger & GitHub
LINQify Documentation is located on GitHub Pages. LINQify blog is located on Blogger. Source code is available on GitHub.
Use LINQ methods as you are used to
[1,2,3,4,5,4,3,2].Select(t => t*2).Where(t => t>5).Skip(1).Take(3).ToArray();
// [8,10,8]
[1,2,3,4,5,4,3,2].Select(t => t*2).TakeWhile(t => t<5).ToArray();
// [2,4]
[1,2,3,4,5,4,3,2].GroupBy(t => t%2).Select(t => ({Key:t.Key, Vals:[...t]})).ToArray();
// [{"Key":1,"Vals":[1,3,5,3]},{"Key":0,"Vals":[2,4,4,2]}]
[1,2,3,4,5,4,3,2].GroupBy(t => t%2).Select(t => ({Key:t.Key, Sum:t.Sum()})).ToArray();
// [{"Key":1,"Sum":12},{"Key":0,"Sum":12}]
[5,6,1,3,5,8,4,9,3,1,5,4,8,9].Distinct().OrderBy(t=>t).ToArray();
// [1,3,4,5,6,8,9]
[{Name:"Jack", Age:18},
{Name:"Joe", Age:22},
{Name:"Jack", Age:20}].OrderBy(t=>t.Name).ThenByDescending(t=>t.Age).ToArray();
// [{"Name":"Jack","Age":20},{"Name":"Jack","Age":18},{"Name":"Joe","Age":22}]
Define custom Sort comparer
function ageComparer (a, b) {
if (a.Age > b.Age) return 1;
if (a.Age < b.Age) return -1;
return 0;
}
let people = [{Name:"Jack", Age:18}, {Name:"Joe", Age:22}, {Name:"Jack", Age:20}];
people.OrderBy(t=>t, ageComparer).ToArray();
// [{"Name":"Jack","Age":18},{"Name":"Jack","Age":20},{"Name":"Joe","Age":22}]
people.OrderByDescending(t=>t, ageComparer).ToArray();
// [{"Name":"Joe","Age":22},{"Name":"Jack","Age":20},{"Name":"Jack","Age":18}]
Define custom Equality comparer
let nameEqualityComparer = {
Equals: (x, y) => x.Name===y.Name,
GetHashCode: obj => obj.Name
}
let people = [{Name:"Jack", Age:18}, {Name:"Joe", Age:22},{Name:"Jack", Age:20}];
people.Distinct(nameEqualityComparer).ToArray();
// [{"Name":"Jack","Age":18},{"Name":"Joe","Age":22}]
// or use DeepComparer
let nameEqComparer = EqualityComparers.DeepComparer(t=>({Name:t.Name}));
people.Distinct(nameEqComparer).ToArray();
// [{"Name":"Jack","Age":18},{"Name":"Joe","Age":22}]
let myhashset = people.ToHashSet(nameEqualityComparer);
[...myhashset]
// [{"Name":"Jack","Age":18},{"Name":"Joe","Age":22}]
myhashset.Add({Name:"Jack", Age:25});
// false
myhashset.Add({Name:"Jane", Age:25});
// true
Easily extend the library
With generator function
Enumerable.setMethod("EvenElements", function*() {
let ind = 0;
for (let t of this)
if (ind++%2 === 0) yield t;
});
["a","b","c","d"].EvenElements().ToArray();
// ["a", "c"]
Or with normal function
Enumerable.setMethod("Variance", function() {
let avg = this.Average();
return this.Select(t => Math.pow(t - avg, 2)).Average();
});
[1,3,4,8,12].Variance();
// 15.440000000000001
Create custom anonymous method
Output the names as many times as they are old
let people = [{Name:"Jack", Age:3}, {Name:"Joe", Age:2}, {Name:"Jane", Age:1}]
people.Custom(function* () {
for (let t of this)
yield* Enumerable.Repeat(t.Name, t.Age)
}).Select(t=>t.toUpperCase()).ToArray()
// ["JACK", "JACK", "JACK", "JOE", "JOE", "JANE"]
Get the oldest person (aka MaxBy)
let people = [{Name:"Jack", Age:18}, {Name:"Joe", Age:22}, {Name:"Jane", Age:20}]
let oldest = people.Custom((source)=>{
let currOldest = source.FirstOrDefault();
for (let t of source) if (t.Age > currOldest.Age) currOldest = t;
return currOldest;
})
oldest
// {Name:"Joe", Age:22}
ToList, ToDictionary, ToHashSet, ToLookup
let mylist = [1,3,4,8,12].ToList();
mylist.Add(15);
[...mylist]
// [1, 3, 4, 8, 12, 15]
let mydict = [1,3,4,8,12].ToDictionary(t=>t, t=>t*2);
[...mydict]
// [{"Key":1,"Value":2},{"Key":3,"Value":6},
// {"Key":4,"Value":8},{"Key":8,"Value":16},
// {"Key":12,"Value":24}]
let myhashset = [1,3,4,8,12].ToHashSet();
myhashset.IsSupersetOf([1,4]);
// true
let groups = [1,3,4,8,12].ToLookup(t=>t>3 ? "big" : "small", t=>t);
for (let group of groups)
console.log(group.Key, [...group]);
// small [1, 3]
// big [4, 8, 12]
ToSet, ToMap, ToArray
[1,3,4,4,8,12].ToSet();
// Set {1, 3, 4, 8, 12}
[1,3,4,4,8,12].ToMap(t=>t, t=>t*2);
// Map {1 => 2, 3 => 6, 4 => 8, 8 => 16, 12 => 24}
[1,3,4,4,8,12].ToMap(t=>t, t=>t*2).ToArray();
// [[1,2],[3,6],[4,8],[8,16],[12,24]]
let upperNames = ["Jane", "Joe", "Jack"].Select(t=>t.toUpperCase());
upperNames.ToArray();
// or
[...upperNames];
// ["JANE", "JOE", "JACK"]
Extends native Array, Map, Set, and String
"Jane Doe".Distinct().Reverse().ToArray();
// ["o", "D", " ", "e", "n", "a", "J"]
new Map([[1,"Jane"],[2,"Joe"],[3,"Jack"]]).Select(t=>`${t[0]}: ${t[1]}`).ToArray();
// ["1: Jane", "2: Joe", "3: Jack"]
new Set([1,4,6,4,7]).Average();
// 4.5
Create IEnumerable from generator
Infinite generator of Prime numbers
function isPrime(num) {
for(let i = 2, s = Math.sqrt(num); i <= s; i++)
if(num % i === 0) return false;
return true;
}
let primeNumbers = Enumerable.From(function* () {
let i = 2;
while (true) {
if (isPrime(i)) yield i;
i++;
}
});
primeNumbers.Take(10).ToArray();
// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Infinite generator of Fibonacci sequence
let fibonacciNumbers = Enumerable.From(function* () {
let current = 0, next = 1;
while (true) {
yield current;
[current, next] = [next, current + next];
}
});
fibonacciNumbers.Take(10).ToArray();
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
With typescript support
noConflict option
import {linqify} from 'linqify';
var lq = linqify.noConflict();
[1,2,3].Select(t=>t*t).ToArray();
// Uncaught TypeError: [1,2,3].Select is not a function
lq.Enumerable.From([1,2,3]).Select(t=>t*t).ToArray();
// or
lq([1,2,3]).Select(t=>t*t).ToArray();
// [1, 4, 9]
Implemented methods in IEnumerable
Aggregate, All, Any, Append, AsEnumerable, Average, Cast, Concat, Contains, Count, Custom, DefaultIfEmpty, Distinct, ElementAt, ElementAtOrDefault, Except, First, FirstOrDefault, ForEach, GroupBy, GroupJoin, Intersect, Join, Last, LastOrDefault, Max, Min, OfType, OrderBy, OrderByDescending, Prepend, Reverse, Select, SelectMany, SequenceEqual, Single, SingleOrDefault, Skip, SkipLast, SkipWhile, Sum, Take, TakeLast, TakeWhile, ToArray, ToDictionary, ToHashSet, ToList, ToLookup, ToMap, ToSet, Union, Where, Zip.