js版的linq查询,类似 LINQ C#,对数组进行的扩展。引用自LINQJS
Selectors
Select
select(selector:(item) => item)
将数组中的每一个元素转换为新的数组,等同于Array.map
var arr = [1, 2, 3, 4, 5];
// 结果: [2, 4, 6, 8, 10]
var doubled = arr.select(function(t){ return t * 2 });
SelectMany
selectMany(selector:(item) => item , [resultSelector:(item,value) => item])
将多个数组的每个元素投影到一个数组,并序列为一个展平数组。
// 对象数组
var arr = [{Name:"A", Values:[1, 2, 3, 4]}, {Name:"B", Values:[5, 6, 7, 8]}];
// 使用默认结果选择器
// 结果: [1, 2, 3, 4, 5, 6, 7, 8]
var res1 = arr.selectMany(function(t){ return t.Values });
// 使用自定义结果选择器
// 结果: [{"Name":"A","Val":1},{"Name":"A","Val":2},...,{"Name":"B","Val":8}]
var res2 = arr.selectMany(function(t){ return t.Values }, function(t, u){ return {Name:t.Name, Val:u}});
// 二维数组
var arr2 = [[1, 2, 3, 4], [5, 6, 7, 8]];
// 使用默认结果选择器
// 结果: [1, 2, 3, 4, 5, 6, 7, 8]
var res1 = arr2.selectMany(function(t){ return t});
// 使用自定义结果选择器
// 结果: [{"Val":1},{"Val":2},{"Val":3},{"Val":4},{"Val":5},{"Val":6},{"Val":7},{"Val":8}]
var res2 = arr2.selectMany(function(t){ return t }, function(t, u){ return {Val:u}});
Take
take(count:number)
从数组的开始返回指定数量的连续元素,等同于Array.slice(0, count)。
var arr = [1, 2, 3, 4, 5];
// 结果: [1, 2]
var res = arr.take(2);
Skip
skip(start:number[, end:number])
绕过数组中指定数量的元素,然后返回其余元素,等同于Array.splice。
var arr = [1, 2, 3, 4, 5];
// 结果: [3, 4, 5]
var res = arr.skip(2);
// 结果: [2, 3, 4]
var res1 = arr.skip(1,4);
First
first(selector:(item, index, array) => boolean[, def:any])
返回数组的第一个元素。
var arr = [1, 2, 3, 4, 5];
// 结果: 1
var t1 = arr.first();
// 使用比较
// 结果: 3
var t2 = arr.first(function(t){ return t > 2 });
// 使用比较和默认值:10,默认值是指在没有满足条件的元素时输出的值
// 结果: 10,找不到满足条件的元素,返回默认值
var t3 = arr.first(function(t){ return t > 10 }, 10);
Last
last(selector:(item, index, array) => boolean[, def:any])
返回数组的最后一个元素。
var arr = [1, 2, 3, 4, 5];
// 结果: 5
var t1 = arr.last();
// 使用比较
// 结果: 5
var t2 = arr.last(function(t){ return t > 2 });
// 使用比较和默认值:10,默认值是指在没有满足条件的元素时输出的值
// 结果: 10,找不到满足条件的元素,返回默认值
var t3 = arr.last(function(t){ return t > 10 }, 10);
Union
union(arr:array)
合并两个数组。
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [5, 6, 7, 8, 9];
// 结果: [1, 2, 3, 4, 5, 6, 7, 8, 9]
var res = arr1.union(arr2);
Intersect
intersect(arr:array[, comparer:(a, b) => boolean)]
两个数组的交集部分。
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [1, 2, 3];
// 结果: [1, 2, 3]
var res = arr1.intersect(arr2);
Except
except(arr:array[, comparer:(a, b) => boolean])
两个数组的差异部分。
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [2, 3, 4];
// 结果: [1, 5]
var res = arr1.except(arr2);
Distinct
distinct([comparer:(a, b) => boolean])
返回数组中不重复的元素。
var arr1 = [1, 2, 2, 3, 3, 4, 5, 5];
// 结果: [1, 2, 3, 4, 5]
var res1 = arr.distinct();
var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:1}];
// 结果: [{Name:"A", Val:1}]
var res2 = arr2.distinct(function(a, b){ return a.Val == b.Val });
Zip
zip(arr: array[, selector:(a, b) => item])
将指定的函数应用于两个数组相同索引的元素(以长度小的数组为准),从而生成结果的序列。
var arr1 = [1, 2, 3, 4, 5];
var arr2 = ["A", "B", "C", "D"];
// 结果: [{Num:1, Letter: "A"},{Num:2, Letter: "B"}, {Num:3, Letter: "C"}, {Num:4, Letter: "D"}]
var res = arr1.zip(arr2, function(a, b){ return {Num:a, Letter:b} });
IndexOf
indexOf(searchElement:any[, fromIndex:number])
返回数组中某个值的第一次出现的索引.
var arr = [1, 2, 3, 2, 5];
// 结果: 1
var index = arr.indexOf(2);
// 结果: 3 起始索引从2开始向后找
var index = arr.indexOf(2, 2);
LastIndexOf
indexOf(searchElement:any[, fromIndex:number])
返回数组中某个值的最后一次出现的索引.
var arr = [1, 2, 3, 4, 5, 3, 4, 5];
// 结果: 5
var index = arr.lastIndexOf(3);
// 结果: 2 起始索引从4开始向前找
var index = arr.lastIndexOf(3,4);
Remove
remove(item: any)
从数组中移除第一次出现的指定对象。
var arr = [1, 2, 3, 4, 5];
// 结果: [1, 3, 4, 5]
arr.remove(2);
RemoveAll
removeAll(selector: (item) => boolean)
移除与指定的条件匹配的所有元素。
var arr = [1, 2, 3, 4, 5];
// 结果: [1, 3, 5]
arr.removeAll(function(t){ return t % 2 == 0 });
OrderBy
orderBy(selector: item => item[, comparer:(a, b) => boolean])
按照升序排列数组元素.
var arr = [{Name:"A", Val:1}, {Name:"a", Val:2}, {Name:"B", Val:1}, {Name:"C", Val:2}];
var res1 = arr.orderBy(function(t){ return t.Name });
var res2 = arr.orderBy(function(t){ return t.Name }, function(a, b){
if(a.toUpperCase() > b.toUpperCase()) return 1;
if(a.toUpperCase() < b.toUpperCase()) return -1;
return 0;
});
var res3 = arr.orderBy(function(t){ return t.Val }, function(a, b){
return a - b
});
OrderByDescending
orderByDescending(selector: item => item[, comparer:(a, b) => boolean])
按照降序排列数组元素.
var arr = [{Name:"A", Val:1}, {Name:"a", Val:2}, {Name:"B", Val:1}, {Name:"C", Val:2}];
var res = arr.orderByDescending(function(t){ return t.Name });
ThenBy / ThenByDescending
thenBy(selector: item => item[, comparer:(a, b) => boolean])
thenByDescending(selector: item => item[, comparer:(a, b) => boolean])
继续排列数组元素,升序/降序,结合 Orderby 和 OrderByDescending 使用可指定多个排序.
var arr = [{Name:"A", Val:1}, {Name:"a", Val:2}, {Name:"B", Val:1}, {Name:"C", Val:2}];
var res1 = arr.orderBy(function(t){ return t.Val })
.thenBy(function(t){ return t.Name });
var res2 = arr.orderBy(function(t){ return t.Val })
.thenByDescending(function(t){ return t.Name });
var res3 = arr.orderByDescending(function(t){ return t.Val })
.thenBy(function(t){ return t.Name });
InnerJoin
outer.innerJoin(inner: array, outerKeySelector: item => item , innerKeySelector: item => item, resultSelector: (outer, inner) => item[, comparer:(a, b) => boolean])
内连接,用于显示根据两个数组中的指定属性符合条件的元素.
var arr1 = [{Name:"A", Val:1}, {Name:"B", Val:2}, {Name:"C", Val:3}];
var arr2 = [{Code:"A"}, {Code:"B"}, {Name:"C", Code:"C"}];
var res1 = arr1.innerJoin(arr2,
function (t) { return t.Name }, // arr1 selector
function (u) { return u.Code }, // arr2 selector
function (t, u) { return { Name: t.Name, Val: t.Val, Code: u.Code } }); // result selector
// using custom comparer
var res2 = arr1.innerJoin(arr2,
function (t) { return t.Name }, // arr1 selector
function (u) { return u.Code }, // arr2 selector
function (t, u) { return { Name: t.Name, Val: t.Val, Code: u.Code } }, // result selector
function (a, b) { return a.toUpperCase() == b.toUpperCase() }); // comparer
GroupJoin
outer.groupJoin(inner: array, groupKeyOuterSelector: item => item , groupKeyInnerSelector: item => item, resultSelector: (outer, inner) => item[, comparer:(a, b) => boolean])
基于key的相等将两个数组的元素相关联,并对结果进行分组.
var arr1 = [{Name:"A", Val:1}, {Name:"B", Val:2}, {Name:"C", Val:3}];
var arr2 = [{Code:"A"}, {Code:"A"}, {Code:"B"}, {Code:"B"}, {Code:"C"}];
var res1 = arr1.groupJoin(arr2,
function(t){ return t.Name }, // arr1 selector
function(u){ return u.Code }, // arr2 selector
function(t, u){ return {Item:t, Group:u} }) ; // result selector
// using custom comparer
var res2 = arr1.groupJoin(arr2,
function(t){ return t.Name }, // arr1 selector
function(u){ return u.Code }, // arr2 selector
function(t, u){ return {Item:t, Group:u} }, // result selector
function(a, b){ return a.toUpperCase() == b.toUpperCase() }); // comparer
GroupBy
groupBy(selector: item => item[, comparer:(a, b) => boolean])
对数组的元素进行分组.
var arr = [{Name:"A", Val:1}, {Name:"B", Val:1}, {Name:"C", Val:2}, {Name:"D", Val:2}];
// 结果: [[{Name:"A", Val:1}, {Name:"B", Val:1}], [{Name:"C", Val:2}, {Name:"D", Val:2}]]
var res = arr.groupBy(function(t){ return t.Val });
res.forEach(function(t){
console.log("Key: " + t.key, "Length: " + t.length);
});
// Key: 1 Length: 2
// Key: 2 Length: 2
ToDictionary
toDictionary(keySelector: item => item, valueSelector: item => item)
数组转换为对象。
var arr = [1, 2, 3, 4, 5];
// 结果: dic = {Num5: 5, Num4: 4, Num3: 3, Num2: 2, Num1: 1}
var dic = arr.toDictionary(t => "Num" + t, u => u );
Aggregations
Aggregate
aggregate(callback: (previous: any, current: any, index: number, array: array)=> item[, initialValue: any])
在数组上应用累加器函数,等同于Array.reduce。
callback函数接受4个参数:之前值、当前值、索引值以及数组本身。
initialValue参数可选,表示初始值。
若指定initialValue,则当作最初使用的previous值;
如果无initialValue,则使用数组的第一个元素作为previous初始值,同时current往后排一位,相比有initialValue值少一次迭代。
var arr = [1, 2, 3, 4, 5];
// 结果:15
var sum = arr.aggregate(function(a, b){ return a + b }, 0);
Min
min([selector: item => item])
返回值数组中的最小值。
var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
// 结果:1
var min1 = arr.min();
var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];
// 结果:1
var min2 = arr2.min(function(t){ return t.Val });
Max
max([selector: item => item])
返回值数组中的最大值。
var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
// 结果:8
var max1 = arr.max();
var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];
// 结果:2
var max2 = arr2.max(function(t){ return t.Val });
Sum
sum([selector: item => item])
计算一个数值数组的和。
var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];
// 结果:36
var sum1 = arr1.sum();
var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];
// 结果:3
var sum2 = arr2.sum(function(t){ return t.Val });
Predicates
Where
where(predicate: item => boolean[, thisObject: any])
基于过滤一数组的值,等同于Array.filter。
var arr = [1, 2, 3, 4, 5];
// 结果:[3, 4, 5]
var res = arr.where(function(t){ return t > 2 }) ;
Any
any(predicate: item => boolean[, thisObject: any])
确定数组中的某个元素是否存在或满足条件,等同于Array.some。
var arr = [1, 2, 3, 4, 5];
// 结果:true
var res1 = arr.any();
// 结果:false
var res2 = arr.any(function(t){ return t > 5 });
All
all(predicate: item => boolean[, thisObject: any])
确定数组中的每个元素是否存在或满足条件,等同于Array.every。
var arr = [1, 2, 3, 4, 5];
// 结果:true
var res = arr.all(function(t){ return t < 6 });
TakeWhile
takeWhile(predicate: item => boolean)
只要指定的条件为true,就返回数组中之前的元素,然后跳过剩余的元素。
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
// 结果:[1, 2, 3]
var res = arr.takeWhile(function(t){ return t % 4 != 0 });
SkipWhile
skipWhile(predicate: item => boolean)
只要指定的条件为true,就会跳过数组中之前的元素,然后返回剩余的元素。
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
// 结果:[ 4, 5, 6, 7, 8]
var res = arr.skipWhile(function(t){ return t % 4 != 0 }) ;
Contains
contains(item: any[, comparer: item => boolean])
确定序列是否包含指定的元素。
var arr1 = [1, 2, 3, 4, 5];
// 结果:true
var res1 = arr.contains(2);
var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:1}];
// 结果:true
var res2 = arr2.contains({Name:"C", Val:1}, function(a, b){ return a.Val == b.Val }) ;
Iterations
Range
range(start: any, count: any)
返回基于start和end参数的数字数组
// 结果:[1,2,3,4,5]
var range = Array.range(1, 5);
ForEach
range(callback: item => any)[, thisObject: any])
对数组的每个元素执行指定的操作,等同于Array.forEach。
var arr = [1, 2, 3, 4, 5];
arr.forEach(function(t){ if(t % 2 ==0) console.log(t); });
DefaultIfEmpty
defaultIfEmpty(val: any)
如果数组为空,则返回指定的数组元素或单例数组中的指定值。
var arr = [1, 2, 3, 4, 5];
// 结果:[5]
var res = arr.where(function(t){ return t > 5 }).defaultIfEmpty(5);