有时界面需要很多数据。但是多次访问服务器效率很低,所以需要检索json数据,最好是像sql查询语句那种

linq.js 插件

LINQ,语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。

而Linq.js就是基于上面的机制,通过javascript来实现的。

实例(https://www.cnblogs.com/landeanfen/p/4672542.html):

//重复输出5个3
Enumerable.Repeat(3).Take(5);//33333
//输出10开始5个值
Enumerable.Range(10,5);//10,11,12,13,14
//随机
Enumerable.Choice("a","b","c","d").Take(5)//随机输出a,b,c,d
//输出大于7个数
Enumerable.Range(1,10).Count("$>7")//3
//输出指定位置的值
Enumerable.Range(1,10).ElementAt(3)//4
var arr = [
{
name:'abcd',
item:{
list:[1,2,3,4]
}
},
{
name:'123',
item:{
list:[3,4,5,6,7,8]
}
},
{
name:'你好',
item:{
list:[5,6,7,8,9]
}
}
]
//选择name字段
Enumerable.From(arr).Select('$.name');//abcd,123,你好
//输出index为1的
Enumerable.From(arr).Select('$.name').Where('v,i=>i==1');//123
//输出所有的list
Enumerable.From(arr).SelectMany('$.item.list');//123434567856789
//输出去重的list
Enumerable.From(arr).SelectMany('$.item.list').Distinct();//123456789
//倒叙
Enumerable.From(arr).SelectMany('$.item.list').Distinct().OrderByDescending();//987654321
//分组
Enumerable.From(arr).SelectMany('$.item.list').Distinct().GroupBy('$%3').Select("$.Key() + ':' + $.ToString('-')");//1:1-4-7,2:2-5-8,0:3-6-9

重点是,引用了从jgit上下载的jslinq-master 下的js 文件无效,也可能是下载错了,最后引用的是https://www.bootcdn.cn/linq.js/ 这里的文件

jquery.linq.js

/*--------------------------------------------------------------------------
* linq.js - LINQ for JavaScript
* ver 2.2.0.2 (Jan. 21th, 2011)
*
* created and maintained by neuecc <ils@neue.cc>
* licensed under Microsoft Public License(Ms-PL)
* http://neue.cc/
* http://linqjs.codeplex.com/
*--------------------------------------------------------------------------*/
jQuery.extend({ Enumerable: (function (){
var Enumerable = function (getEnumerator)
{
this.GetEnumerator = getEnumerator;
} // Generator Enumerable.Choice = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments; return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function ()
{
return this.Yield(args[Math.floor(Math.random() * args.length)]);
},
Functions.Blank);
});
} Enumerable.Cycle = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments; return new Enumerable(function ()
{
var index = 0;
return new IEnumerator(
Functions.Blank,
function ()
{
if (index >= args.length) index = 0;
return this.Yield(args[index++]);
},
Functions.Blank);
});
} Enumerable.Empty = function ()
{
return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return false; },
Functions.Blank);
});
} Enumerable.From = function (obj)
{
if (obj == null)
{
return Enumerable.Empty();
}
if (obj instanceof Enumerable)
{
return obj;
}
if (typeof obj == Types.Number || typeof obj == Types.Boolean)
{
return Enumerable.Repeat(obj, 1);
}
if (typeof obj == Types.String)
{
return new Enumerable(function ()
{
var index = 0;
return new IEnumerator(
Functions.Blank,
function ()
{
return (index < obj.length) ? this.Yield(obj.charAt(index++)) : false;
},
Functions.Blank);
});
}
if (typeof obj != Types.Function)
{
// array or array like object
if (typeof obj.length == Types.Number)
{
return new ArrayEnumerable(obj);
} // JScript's IEnumerable
if (!(obj instanceof Object) && Utils.IsIEnumerable(obj))
{
return new Enumerable(function ()
{
var isFirst = true;
var enumerator;
return new IEnumerator(
function () { enumerator = new Enumerator(obj); },
function ()
{
if (isFirst) isFirst = false;
else enumerator.moveNext(); return (enumerator.atEnd()) ? false : this.Yield(enumerator.item());
},
Functions.Blank);
});
}
} // case function/object : Create KeyValuePair[]
return new Enumerable(function ()
{
var array = [];
var index = 0; return new IEnumerator(
function ()
{
for (var key in obj)
{
if (!(obj[key] instanceof Function))
{
array.push({ Key: key, Value: obj[key] });
}
}
},
function ()
{
return (index < array.length)
? this.Yield(array[index++])
: false;
},
Functions.Blank);
});
}, Enumerable.Return = function (element)
{
return Enumerable.Repeat(element, 1);
} // Overload:function(input, pattern)
// Overload:function(input, pattern, flags)
Enumerable.Matches = function (input, pattern, flags)
{
if (flags == null) flags = "";
if (pattern instanceof RegExp)
{
flags += (pattern.ignoreCase) ? "i" : "";
flags += (pattern.multiline) ? "m" : "";
pattern = pattern.source;
}
if (flags.indexOf("g") === -1) flags += "g"; return new Enumerable(function ()
{
var regex;
return new IEnumerator(
function () { regex = new RegExp(pattern, flags) },
function ()
{
var match = regex.exec(input);
return (match) ? this.Yield(match) : false;
},
Functions.Blank);
});
} // Overload:function(start, count)
// Overload:function(start, count, step)
Enumerable.Range = function (start, count, step)
{
if (step == null) step = 1;
return Enumerable.ToInfinity(start, step).Take(count);
} // Overload:function(start, count)
// Overload:function(start, count, step)
Enumerable.RangeDown = function (start, count, step)
{
if (step == null) step = 1;
return Enumerable.ToNegativeInfinity(start, step).Take(count);
} // Overload:function(start, to)
// Overload:function(start, to, step)
Enumerable.RangeTo = function (start, to, step)
{
if (step == null) step = 1;
return (start < to)
? Enumerable.ToInfinity(start, step).TakeWhile(function (i) { return i <= to; })
: Enumerable.ToNegativeInfinity(start, step).TakeWhile(function (i) { return i >= to; })
} // Overload:function(obj)
// Overload:function(obj, num)
Enumerable.Repeat = function (obj, num)
{
if (num != null) return Enumerable.Repeat(obj).Take(num); return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(obj); },
Functions.Blank);
});
} Enumerable.RepeatWithFinalize = function (initializer, finalizer)
{
initializer = Utils.CreateLambda(initializer);
finalizer = Utils.CreateLambda(finalizer); return new Enumerable(function ()
{
var element;
return new IEnumerator(
function () { element = initializer(); },
function () { return this.Yield(element); },
function ()
{
if (element != null)
{
finalizer(element);
element = null;
}
});
});
} // Overload:function(func)
// Overload:function(func, count)
Enumerable.Generate = function (func, count)
{
if (count != null) return Enumerable.Generate(func).Take(count);
func = Utils.CreateLambda(func); return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(func()); },
Functions.Blank);
});
} // Overload:function()
// Overload:function(start)
// Overload:function(start, step)
Enumerable.ToInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1; return new Enumerable(function ()
{
var value;
return new IEnumerator(
function () { value = start - step },
function () { return this.Yield(value += step); },
Functions.Blank);
});
} // Overload:function()
// Overload:function(start)
// Overload:function(start, step)
Enumerable.ToNegativeInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1; return new Enumerable(function ()
{
var value;
return new IEnumerator(
function () { value = start + step },
function () { return this.Yield(value -= step); },
Functions.Blank);
});
} Enumerable.Unfold = function (seed, func)
{
func = Utils.CreateLambda(func); return new Enumerable(function ()
{
var isFirst = true;
var value;
return new IEnumerator(
Functions.Blank,
function ()
{
if (isFirst)
{
isFirst = false;
value = seed;
return this.Yield(value);
}
value = func(value);
return this.Yield(value);
},
Functions.Blank);
});
} // Extension Methods Enumerable.prototype =
{
/* Projection and Filtering Methods */ // Overload:function(func)
// Overload:function(func, resultSelector<element>)
// Overload:function(func, resultSelector<element, nestLevel>)
CascadeBreadthFirst: function (func, resultSelector)
{
var source = this;
func = Utils.CreateLambda(func);
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumerator;
var nestLevel = 0;
var buffer = []; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (enumerator.MoveNext())
{
buffer.push(enumerator.Current());
return this.Yield(resultSelector(enumerator.Current(), nestLevel));
} var next = Enumerable.From(buffer).SelectMany(function (x) { return func(x); });
if (!next.Any())
{
return false;
}
else
{
nestLevel++;
buffer = [];
Utils.Dispose(enumerator);
enumerator = next.GetEnumerator();
}
}
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(func)
// Overload:function(func, resultSelector<element>)
// Overload:function(func, resultSelector<element, nestLevel>)
CascadeDepthFirst: function (func, resultSelector)
{
var source = this;
func = Utils.CreateLambda(func);
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumeratorStack = [];
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (enumerator.MoveNext())
{
var value = resultSelector(enumerator.Current(), enumeratorStack.length);
enumeratorStack.push(enumerator);
enumerator = Enumerable.From(func(enumerator.Current())).GetEnumerator();
return this.Yield(value);
} if (enumeratorStack.length <= 0) return false;
Utils.Dispose(enumerator);
enumerator = enumeratorStack.pop();
}
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Enumerable.From(enumeratorStack).ForEach(function (s) { s.Dispose(); }) }
});
});
}, Flatten: function ()
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var middleEnumerator = null; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (middleEnumerator != null)
{
if (middleEnumerator.MoveNext())
{
return this.Yield(middleEnumerator.Current());
}
else
{
middleEnumerator = null;
}
} if (enumerator.MoveNext())
{
if (enumerator.Current() instanceof Array)
{
Utils.Dispose(middleEnumerator);
middleEnumerator = Enumerable.From(enumerator.Current())
.SelectMany(Functions.Identity)
.Flatten()
.GetEnumerator();
continue;
}
else
{
return this.Yield(enumerator.Current());
}
} return false;
}
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Utils.Dispose(middleEnumerator); }
});
});
}, Pairwise: function (selector)
{
var source = this;
selector = Utils.CreateLambda(selector); return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
enumerator.MoveNext();
},
function ()
{
var prev = enumerator.Current();
return (enumerator.MoveNext())
? this.Yield(selector(prev, enumerator.Current()))
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(func)
// Overload:function(seed,func<value,element>)
// Overload:function(seed,func<value,element>,resultSelector)
Scan: function (seed, func, resultSelector)
{
if (resultSelector != null) return this.Scan(seed, func).Select(resultSelector); var isUseSeed;
if (func == null)
{
func = Utils.CreateLambda(seed); // arguments[0]
isUseSeed = false;
}
else
{
func = Utils.CreateLambda(func);
isUseSeed = true;
}
var source = this; return new Enumerable(function ()
{
var enumerator;
var value;
var isFirst = true; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (isFirst)
{
isFirst = false;
if (!isUseSeed)
{
if (enumerator.MoveNext())
{
return this.Yield(value = enumerator.Current());
}
}
else
{
return this.Yield(value = seed);
}
} return (enumerator.MoveNext())
? this.Yield(value = func(value, enumerator.Current()))
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(selector<element>)
// Overload:function(selector<element,index>)
Select: function (selector)
{
var source = this;
selector = Utils.CreateLambda(selector); return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext())
? this.Yield(selector(enumerator.Current(), index++))
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(collectionSelector<element>)
// Overload:function(collectionSelector<element,index>)
// Overload:function(collectionSelector<element>,resultSelector)
// Overload:function(collectionSelector<element,index>,resultSelector)
SelectMany: function (collectionSelector, resultSelector)
{
var source = this;
collectionSelector = Utils.CreateLambda(collectionSelector);
if (resultSelector == null) resultSelector = function (a, b) { return b; }
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumerator;
var middleEnumerator = undefined;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (middleEnumerator === undefined)
{
if (!enumerator.MoveNext()) return false;
}
do
{
if (middleEnumerator == null)
{
var middleSeq = collectionSelector(enumerator.Current(), index++);
middleEnumerator = Enumerable.From(middleSeq).GetEnumerator();
}
if (middleEnumerator.MoveNext())
{
return this.Yield(resultSelector(enumerator.Current(), middleEnumerator.Current()));
}
Utils.Dispose(middleEnumerator);
middleEnumerator = null;
} while (enumerator.MoveNext())
return false;
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Utils.Dispose(middleEnumerator); }
})
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
Where: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (enumerator.MoveNext())
{
if (predicate(enumerator.Current(), index++))
{
return this.Yield(enumerator.Current());
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, OfType: function (type)
{
var typeName;
switch (type)
{
case Number: typeName = Types.Number; break;
case String: typeName = Types.String; break;
case Boolean: typeName = Types.Boolean; break;
case Function: typeName = Types.Function; break;
default: typeName = null; break;
}
return (typeName === null)
? this.Where(function (x) { return x instanceof type })
: this.Where(function (x) { return typeof x === typeName });
}, // Overload:function(second,selector<outer,inner>)
// Overload:function(second,selector<outer,inner,index>)
Zip: function (second, selector)
{
selector = Utils.CreateLambda(selector);
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var index = 0; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = Enumerable.From(second).GetEnumerator();
},
function ()
{
if (firstEnumerator.MoveNext() && secondEnumerator.MoveNext())
{
return this.Yield(selector(firstEnumerator.Current(), secondEnumerator.Current(), index++));
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, /* Join Methods */ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
// Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
Join: function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
{
outerKeySelector = Utils.CreateLambda(outerKeySelector);
innerKeySelector = Utils.CreateLambda(innerKeySelector);
resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var outerEnumerator;
var lookup;
var innerElements = null;
var innerCount = 0; return new IEnumerator(
function ()
{
outerEnumerator = source.GetEnumerator();
lookup = Enumerable.From(inner).ToLookup(innerKeySelector, Functions.Identity, compareSelector);
},
function ()
{
while (true)
{
if (innerElements != null)
{
var innerElement = innerElements[innerCount++];
if (innerElement !== undefined)
{
return this.Yield(resultSelector(outerEnumerator.Current(), innerElement));
} innerElement = null;
innerCount = 0;
} if (outerEnumerator.MoveNext())
{
var key = outerKeySelector(outerEnumerator.Current());
innerElements = lookup.Get(key).ToArray();
}
else
{
return false;
}
}
},
function () { Utils.Dispose(outerEnumerator); })
});
}, // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
// Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
GroupJoin: function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
{
outerKeySelector = Utils.CreateLambda(outerKeySelector);
innerKeySelector = Utils.CreateLambda(innerKeySelector);
resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator = source.GetEnumerator();
var lookup = null; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
lookup = Enumerable.From(inner).ToLookup(innerKeySelector, Functions.Identity, compareSelector);
},
function ()
{
if (enumerator.MoveNext())
{
var innerElement = lookup.Get(outerKeySelector(enumerator.Current()));
return this.Yield(resultSelector(enumerator.Current(), innerElement));
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, /* Set Methods */ All: function (predicate)
{
predicate = Utils.CreateLambda(predicate); var result = true;
this.ForEach(function (x)
{
if (!predicate(x))
{
result = false;
return false; // break
}
});
return result;
}, // Overload:function()
// Overload:function(predicate)
Any: function (predicate)
{
predicate = Utils.CreateLambda(predicate); var enumerator = this.GetEnumerator();
try
{
if (arguments.length == 0) return enumerator.MoveNext(); // case:function() while (enumerator.MoveNext()) // case:function(predicate)
{
if (predicate(enumerator.Current())) return true;
}
return false;
}
finally { Utils.Dispose(enumerator); }
}, Concat: function (second)
{
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator; return new IEnumerator(
function () { firstEnumerator = source.GetEnumerator(); },
function ()
{
if (secondEnumerator == null)
{
if (firstEnumerator.MoveNext()) return this.Yield(firstEnumerator.Current());
secondEnumerator = Enumerable.From(second).GetEnumerator();
}
if (secondEnumerator.MoveNext()) return this.Yield(secondEnumerator.Current());
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, Insert: function (index, second)
{
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var count = 0;
var isEnumerated = false; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = Enumerable.From(second).GetEnumerator();
},
function ()
{
if (count == index && secondEnumerator.MoveNext())
{
isEnumerated = true;
return this.Yield(secondEnumerator.Current());
}
if (firstEnumerator.MoveNext())
{
count++;
return this.Yield(firstEnumerator.Current());
}
if (!isEnumerated && secondEnumerator.MoveNext())
{
return this.Yield(secondEnumerator.Current());
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, Alternate: function (value)
{
value = Enumerable.Return(value);
return this.SelectMany(function (elem)
{
return Enumerable.Return(elem).Concat(value);
}).TakeExceptLast();
}, // Overload:function(value)
// Overload:function(value, compareSelector)
Contains: function (value, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var enumerator = this.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
if (compareSelector(enumerator.Current()) === value) return true;
}
return false;
}
finally { Utils.Dispose(enumerator) }
}, DefaultIfEmpty: function (defaultValue)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var isFirst = true; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (enumerator.MoveNext())
{
isFirst = false;
return this.Yield(enumerator.Current());
}
else if (isFirst)
{
isFirst = false;
return this.Yield(defaultValue);
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function()
// Overload:function(compareSelector)
Distinct: function (compareSelector)
{
return this.Except(Enumerable.Empty(), compareSelector);
}, // Overload:function(second)
// Overload:function(second, compareSelector)
Except: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator;
var keys; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
Enumerable.From(second).ForEach(function (key) { keys.Add(key); });
},
function ()
{
while (enumerator.MoveNext())
{
var current = enumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(second)
// Overload:function(second, compareSelector)
Intersect: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator;
var keys;
var outs; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator(); keys = new Dictionary(compareSelector);
Enumerable.From(second).ForEach(function (key) { keys.Add(key); });
outs = new Dictionary(compareSelector);
},
function ()
{
while (enumerator.MoveNext())
{
var current = enumerator.Current();
if (!outs.Contains(current) && keys.Contains(current))
{
outs.Add(current);
return this.Yield(current);
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(second)
// Overload:function(second, compareSelector)
SequenceEqual: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector); var firstEnumerator = this.GetEnumerator();
try
{
var secondEnumerator = Enumerable.From(second).GetEnumerator();
try
{
while (firstEnumerator.MoveNext())
{
if (!secondEnumerator.MoveNext()
|| compareSelector(firstEnumerator.Current()) !== compareSelector(secondEnumerator.Current()))
{
return false;
}
} if (secondEnumerator.MoveNext()) return false;
return true;
}
finally { Utils.Dispose(secondEnumerator); }
}
finally { Utils.Dispose(firstEnumerator); }
}, Union: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var keys; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
},
function ()
{
var current;
if (secondEnumerator === undefined)
{
while (firstEnumerator.MoveNext())
{
current = firstEnumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
secondEnumerator = Enumerable.From(second).GetEnumerator();
}
while (secondEnumerator.MoveNext())
{
current = secondEnumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, /* Ordering Methods */ OrderBy: function (keySelector)
{
return new OrderedEnumerable(this, keySelector, false);
}, OrderByDescending: function (keySelector)
{
return new OrderedEnumerable(this, keySelector, true);
}, Reverse: function ()
{
var source = this; return new Enumerable(function ()
{
var buffer;
var index; return new IEnumerator(
function ()
{
buffer = source.ToArray();
index = buffer.length;
},
function ()
{
return (index > 0)
? this.Yield(buffer[--index])
: false;
},
Functions.Blank)
});
}, Shuffle: function ()
{
var source = this; return new Enumerable(function ()
{
var buffer; return new IEnumerator(
function () { buffer = source.ToArray(); },
function ()
{
if (buffer.length > 0)
{
var i = Math.floor(Math.random() * buffer.length);
return this.Yield(buffer.splice(i, 1)[0]);
}
return false;
},
Functions.Blank)
});
}, /* Grouping Methods */ // Overload:function(keySelector)
// Overload:function(keySelector,elementSelector)
// Overload:function(keySelector,elementSelector,resultSelector)
// Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
GroupBy: function (keySelector, elementSelector, resultSelector, compareSelector)
{
var source = this;
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
if (resultSelector != null) resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector); return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = source.ToLookup(keySelector, elementSelector, compareSelector)
.ToEnumerable()
.GetEnumerator();
},
function ()
{
while (enumerator.MoveNext())
{
return (resultSelector == null)
? this.Yield(enumerator.Current())
: this.Yield(resultSelector(enumerator.Current().Key(), enumerator.Current()));
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(keySelector)
// Overload:function(keySelector,elementSelector)
// Overload:function(keySelector,elementSelector,resultSelector)
// Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
PartitionBy: function (keySelector, elementSelector, resultSelector, compareSelector)
{ var source = this;
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var hasResultSelector;
if (resultSelector == null)
{
hasResultSelector = false;
resultSelector = function (key, group) { return new Grouping(key, group) }
}
else
{
hasResultSelector = true;
resultSelector = Utils.CreateLambda(resultSelector);
} return new Enumerable(function ()
{
var enumerator;
var key;
var compareKey;
var group = []; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
key = keySelector(enumerator.Current());
compareKey = compareSelector(key);
group.push(elementSelector(enumerator.Current()));
}
},
function ()
{
var hasNext;
while ((hasNext = enumerator.MoveNext()) == true)
{
if (compareKey === compareSelector(keySelector(enumerator.Current())))
{
group.push(elementSelector(enumerator.Current()));
}
else break;
} if (group.length > 0)
{
var result = (hasResultSelector)
? resultSelector(key, Enumerable.From(group))
: resultSelector(key, group);
if (hasNext)
{
key = keySelector(enumerator.Current());
compareKey = compareSelector(key);
group = [elementSelector(enumerator.Current())];
}
else group = []; return this.Yield(result);
} return false;
},
function () { Utils.Dispose(enumerator); })
});
}, BufferWithCount: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
var array = [];
var index = 0;
while (enumerator.MoveNext())
{
array.push(enumerator.Current());
if (++index >= count) return this.Yield(array);
}
if (array.length > 0) return this.Yield(array);
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, /* Aggregate Methods */ // Overload:function(func)
// Overload:function(seed,func)
// Overload:function(seed,func,resultSelector)
Aggregate: function (seed, func, resultSelector)
{
return this.Scan(seed, func, resultSelector).Last();
}, // Overload:function()
// Overload:function(selector)
Average: function (selector)
{
selector = Utils.CreateLambda(selector); var sum = 0;
var count = 0;
this.ForEach(function (x)
{
sum += selector(x);
++count;
}); return sum / count;
}, // Overload:function()
// Overload:function(predicate)
Count: function (predicate)
{
predicate = (predicate == null) ? Functions.True : Utils.CreateLambda(predicate); var count = 0;
this.ForEach(function (x, i)
{
if (predicate(x, i)) ++count;
});
return count;
}, // Overload:function()
// Overload:function(selector)
Max: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(function (a, b) { return (a > b) ? a : b; });
}, // Overload:function()
// Overload:function(selector)
Min: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(function (a, b) { return (a < b) ? a : b; });
}, MaxBy: function (keySelector)
{
keySelector = Utils.CreateLambda(keySelector);
return this.Aggregate(function (a, b) { return (keySelector(a) > keySelector(b)) ? a : b });
}, MinBy: function (keySelector)
{
keySelector = Utils.CreateLambda(keySelector);
return this.Aggregate(function (a, b) { return (keySelector(a) < keySelector(b)) ? a : b });
}, // Overload:function()
// Overload:function(selector)
Sum: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(0, function (a, b) { return a + b; });
}, /* Paging Methods */ ElementAt: function (index)
{
var value;
var found = false;
this.ForEach(function (x, i)
{
if (i == index)
{
value = x;
found = true;
return false;
}
}); if (!found) throw new Error("index is less than 0 or greater than or equal to the number of elements in source.");
return value;
}, ElementAtOrDefault: function (index, defaultValue)
{
var value;
var found = false;
this.ForEach(function (x, i)
{
if (i == index)
{
value = x;
found = true;
return false;
}
}); return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
First: function (predicate)
{
if (predicate != null) return this.Where(predicate).First(); var value;
var found = false;
this.ForEach(function (x)
{
value = x;
found = true;
return false;
}); if (!found) throw new Error("First:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
FirstOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).FirstOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
value = x;
found = true;
return false;
});
return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
Last: function (predicate)
{
if (predicate != null) return this.Where(predicate).Last(); var value;
var found = false;
this.ForEach(function (x)
{
found = true;
value = x;
}); if (!found) throw new Error("Last:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
LastOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).LastOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
found = true;
value = x;
});
return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
Single: function (predicate)
{
if (predicate != null) return this.Where(predicate).Single(); var value;
var found = false;
this.ForEach(function (x)
{
if (!found)
{
found = true;
value = x;
}
else throw new Error("Single:sequence contains more than one element.");
}); if (!found) throw new Error("Single:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
SingleOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).SingleOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
if (!found)
{
found = true;
value = x;
}
else throw new Error("Single:sequence contains more than one element.");
}); return (!found) ? defaultValue : value;
}, Skip: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
while (index++ < count && enumerator.MoveNext()) { };
},
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
SkipWhile: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0;
var isSkipEnd = false; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (!isSkipEnd)
{
if (enumerator.MoveNext())
{
if (!predicate(enumerator.Current(), index++))
{
isSkipEnd = true;
return this.Yield(enumerator.Current());
}
continue;
}
else return false;
} return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false; },
function () { Utils.Dispose(enumerator); });
});
}, Take: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (index++ < count && enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); }
)
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
TakeWhile: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext() && predicate(enumerator.Current(), index++))
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function()
// Overload:function(count)
TakeExceptLast: function (count)
{
if (count == null) count = 1;
var source = this; return new Enumerable(function ()
{
if (count <= 0) return source.GetEnumerator(); // do nothing var enumerator;
var q = []; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (enumerator.MoveNext())
{
if (q.length == count)
{
q.push(enumerator.Current());
return this.Yield(q.shift());
}
q.push(enumerator.Current());
}
return false;
},
function () { Utils.Dispose(enumerator); });
});
}, TakeFromLast: function (count)
{
if (count <= 0 || count == null) return Enumerable.Empty();
var source = this; return new Enumerable(function ()
{
var sourceEnumerator;
var enumerator;
var q = []; return new IEnumerator(
function () { sourceEnumerator = source.GetEnumerator(); },
function ()
{
while (sourceEnumerator.MoveNext())
{
if (q.length == count) q.shift()
q.push(sourceEnumerator.Current());
}
if (enumerator == null)
{
enumerator = Enumerable.From(q).GetEnumerator();
}
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, IndexOf: function (item)
{
var found = null;
this.ForEach(function (x, i)
{
if (x === item)
{
found = i;
return true;
}
}); return (found !== null) ? found : -1;
}, LastIndexOf: function (item)
{
var result = -1;
this.ForEach(function (x, i)
{
if (x === item) result = i;
}); return result;
}, /* Convert Methods */ ToArray: function ()
{
var array = [];
this.ForEach(function (x) { array.push(x) });
return array;
}, // Overload:function(keySelector)
// Overload:function(keySelector, elementSelector)
// Overload:function(keySelector, elementSelector, compareSelector)
ToLookup: function (keySelector, elementSelector, compareSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector); var dict = new Dictionary(compareSelector);
this.ForEach(function (x)
{
var key = keySelector(x);
var element = elementSelector(x); var array = dict.Get(key);
if (array !== undefined) array.push(element);
else dict.Add(key, [element]);
});
return new Lookup(dict);
}, ToObject: function (keySelector, elementSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector); var obj = {};
this.ForEach(function (x)
{
obj[keySelector(x)] = elementSelector(x);
});
return obj;
}, // Overload:function(keySelector, elementSelector)
// Overload:function(keySelector, elementSelector, compareSelector)
ToDictionary: function (keySelector, elementSelector, compareSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector); var dict = new Dictionary(compareSelector);
this.ForEach(function (x)
{
dict.Add(keySelector(x), elementSelector(x));
});
return dict;
}, // Overload:function()
// Overload:function(replacer)
// Overload:function(replacer, space)
ToJSON: function (replacer, space)
{
return JSON.stringify(this.ToArray(), replacer, space);
}, // Overload:function()
// Overload:function(separator)
// Overload:function(separator,selector)
ToString: function (separator, selector)
{
if (separator == null) separator = "";
if (selector == null) selector = Functions.Identity; return this.Select(selector).ToArray().join(separator);
}, /* Action Methods */ // Overload:function(action<element>)
// Overload:function(action<element,index>)
Do: function (action)
{
var source = this;
action = Utils.CreateLambda(action); return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (enumerator.MoveNext())
{
action(enumerator.Current(), index++);
return this.Yield(enumerator.Current());
}
return false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(action<element>)
// Overload:function(action<element,index>)
// Overload:function(func<element,bool>)
// Overload:function(func<element,index,bool>)
ForEach: function (action)
{
action = Utils.CreateLambda(action); var index = 0;
var enumerator = this.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
if (action(enumerator.Current(), index++) === false) break;
}
}
finally { Utils.Dispose(enumerator); }
}, // Overload:function()
// Overload:function(separator)
// Overload:function(separator,selector)
Write: function (separator, selector)
{
if (separator == null) separator = "";
selector = Utils.CreateLambda(selector); var isFirst = true;
this.ForEach(function (item)
{
if (isFirst) isFirst = false;
else document.write(separator);
document.write(selector(item));
});
}, // Overload:function()
// Overload:function(selector)
WriteLine: function (selector)
{
selector = Utils.CreateLambda(selector); this.ForEach(function (item)
{
document.write(selector(item));
document.write("<br />");
});
}, Force: function ()
{
var enumerator = this.GetEnumerator(); try { while (enumerator.MoveNext()) { } }
finally { Utils.Dispose(enumerator); }
}, /* Functional Methods */ Let: function (func)
{
func = Utils.CreateLambda(func);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = Enumerable.From(func(source)).GetEnumerator();
},
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, Share: function ()
{
var source = this;
var sharedEnumerator; return new Enumerable(function ()
{
return new IEnumerator(
function ()
{
if (sharedEnumerator == null)
{
sharedEnumerator = source.GetEnumerator();
}
},
function ()
{
return (sharedEnumerator.MoveNext())
? this.Yield(sharedEnumerator.Current())
: false;
},
Functions.Blank
)
});
}, MemoizeAll: function ()
{
var source = this;
var cache;
var enumerator; return new Enumerable(function ()
{
var index = -1; return new IEnumerator(
function ()
{
if (enumerator == null)
{
enumerator = source.GetEnumerator();
cache = [];
}
},
function ()
{
index++;
if (cache.length <= index)
{
return (enumerator.MoveNext())
? this.Yield(cache[index] = enumerator.Current())
: false;
} return this.Yield(cache[index]);
},
Functions.Blank
)
});
}, /* Error Handling Methods */ Catch: function (handler)
{
handler = Utils.CreateLambda(handler);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
try
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
}
catch (e)
{
handler(e);
return false;
}
},
function () { Utils.Dispose(enumerator); });
});
}, Finally: function (finallyAction)
{
finallyAction = Utils.CreateLambda(finallyAction);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { finallyAction(); }
});
});
}, /* For Debug Methods */ // Overload:function()
// Overload:function(message)
// Overload:function(message,selector)
Trace: function (message, selector)
{
if (message == null) message = "Trace";
selector = Utils.CreateLambda(selector); return this.Do(function (item)
{
console.log(message, ":", selector(item));
});
}
} // private // static functions
var Functions =
{
Identity: function (x) { return x; },
True: function () { return true; },
Blank: function () { }
} // static const
var Types =
{
Boolean: typeof true,
Number: typeof 0,
String: typeof "",
Object: typeof {},
Undefined: typeof undefined,
Function: typeof function () { }
} // static utility methods
var Utils =
{
// Create anonymous function from lambda expression string
CreateLambda: function (expression)
{
if (expression == null) return Functions.Identity;
if (typeof expression == Types.String)
{
if (expression == "")
{
return Functions.Identity;
}
else if (expression.indexOf("=>") == -1)
{
return new Function("$,$$,$$$,$$$$", "return " + expression);
}
else
{
var expr = expression.match(/^[(\s]*([^()]*?)[)\s]*=>(.*)/);
return new Function(expr[1], "return " + expr[2]);
}
}
return expression;
}, IsIEnumerable: function (obj)
{
if (typeof Enumerator != Types.Undefined)
{
try
{
new Enumerator(obj);
return true;
}
catch (e) { }
}
return false;
}, Compare: function (a, b)
{
return (a === b) ? 0
: (a > b) ? 1
: -1;
}, Dispose: function (obj)
{
if (obj != null) obj.Dispose();
}
} // IEnumerator State
var State = { Before: 0, Running: 1, After: 2 } // name "Enumerator" is conflict JScript's "Enumerator"
var IEnumerator = function (initialize, tryGetNext, dispose)
{
var yielder = new Yielder();
var state = State.Before; this.Current = yielder.Current;
this.MoveNext = function ()
{
try
{
switch (state)
{
case State.Before:
state = State.Running;
initialize(); // fall through
case State.Running:
if (tryGetNext.apply(yielder))
{
return true;
}
else
{
this.Dispose();
return false;
}
case State.After:
return false;
}
}
catch (e)
{
this.Dispose();
throw e;
}
}
this.Dispose = function ()
{
if (state != State.Running) return; try { dispose(); }
finally { state = State.After; }
}
} // for tryGetNext
var Yielder = function ()
{
var current = null;
this.Current = function () { return current; }
this.Yield = function (value)
{
current = value;
return true;
}
} // for OrderBy/ThenBy var OrderedEnumerable = function (source, keySelector, descending, parent)
{
this.source = source;
this.keySelector = Utils.CreateLambda(keySelector);
this.descending = descending;
this.parent = parent;
}
OrderedEnumerable.prototype = new Enumerable(); OrderedEnumerable.prototype.CreateOrderedEnumerable = function (keySelector, descending)
{
return new OrderedEnumerable(this.source, keySelector, descending, this);
} OrderedEnumerable.prototype.ThenBy = function (keySelector)
{
return this.CreateOrderedEnumerable(keySelector, false);
} OrderedEnumerable.prototype.ThenByDescending = function (keySelector)
{
return this.CreateOrderedEnumerable(keySelector, true);
} OrderedEnumerable.prototype.GetEnumerator = function ()
{
var self = this;
var buffer;
var indexes;
var index = 0; return new IEnumerator(
function ()
{
buffer = [];
indexes = [];
self.source.ForEach(function (item, index)
{
buffer.push(item);
indexes.push(index);
});
var sortContext = SortContext.Create(self, null);
sortContext.GenerateKeys(buffer); indexes.sort(function (a, b) { return sortContext.Compare(a, b); });
},
function ()
{
return (index < indexes.length)
? this.Yield(buffer[indexes[index++]])
: false;
},
Functions.Blank
)
} var SortContext = function (keySelector, descending, child)
{
this.keySelector = keySelector;
this.descending = descending;
this.child = child;
this.keys = null;
} SortContext.Create = function (orderedEnumerable, currentContext)
{
var context = new SortContext(orderedEnumerable.keySelector, orderedEnumerable.descending, currentContext);
if (orderedEnumerable.parent != null) return SortContext.Create(orderedEnumerable.parent, context);
return context;
} SortContext.prototype.GenerateKeys = function (source)
{
var len = source.length;
var keySelector = this.keySelector;
var keys = new Array(len);
for (var i = 0; i < len; i++) keys[i] = keySelector(source[i]);
this.keys = keys; if (this.child != null) this.child.GenerateKeys(source);
} SortContext.prototype.Compare = function (index1, index2)
{
var comparison = Utils.Compare(this.keys[index1], this.keys[index2]); if (comparison == 0)
{
if (this.child != null) return this.child.Compare(index1, index2)
comparison = Utils.Compare(index1, index2);
} return (this.descending) ? -comparison : comparison;
} // optimize array or arraylike object var ArrayEnumerable = function (source)
{
this.source = source;
}
ArrayEnumerable.prototype = new Enumerable(); ArrayEnumerable.prototype.Any = function (predicate)
{
return (predicate == null)
? (this.source.length > 0)
: Enumerable.prototype.Any.apply(this, arguments);
} ArrayEnumerable.prototype.Count = function (predicate)
{
return (predicate == null)
? this.source.length
: Enumerable.prototype.Count.apply(this, arguments);
} ArrayEnumerable.prototype.ElementAt = function (index)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: Enumerable.prototype.ElementAt.apply(this, arguments);
} ArrayEnumerable.prototype.ElementAtOrDefault = function (index, defaultValue)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: defaultValue;
} ArrayEnumerable.prototype.First = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[0]
: Enumerable.prototype.First.apply(this, arguments);
} ArrayEnumerable.prototype.FirstOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return Enumerable.prototype.FirstOrDefault.apply(this, arguments);
} return this.source.length > 0 ? this.source[0] : defaultValue;
} ArrayEnumerable.prototype.Last = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[this.source.length - 1]
: Enumerable.prototype.Last.apply(this, arguments);
} ArrayEnumerable.prototype.LastOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return Enumerable.prototype.LastOrDefault.apply(this, arguments);
} return this.source.length > 0 ? this.source[this.source.length - 1] : defaultValue;
} ArrayEnumerable.prototype.Skip = function (count)
{
var source = this.source; return new Enumerable(function ()
{
var index; return new IEnumerator(
function () { index = (count < 0) ? 0 : count },
function ()
{
return (index < source.length)
? this.Yield(source[index++])
: false;
},
Functions.Blank);
});
}; ArrayEnumerable.prototype.TakeExceptLast = function (count)
{
if (count == null) count = 1;
return this.Take(this.source.length - count);
} ArrayEnumerable.prototype.TakeFromLast = function (count)
{
return this.Skip(this.source.length - count);
} ArrayEnumerable.prototype.Reverse = function ()
{
var source = this.source; return new Enumerable(function ()
{
var index; return new IEnumerator(
function ()
{
index = source.length;
},
function ()
{
return (index > 0)
? this.Yield(source[--index])
: false;
},
Functions.Blank)
});
} ArrayEnumerable.prototype.SequenceEqual = function (second, compareSelector)
{
if ((second instanceof ArrayEnumerable || second instanceof Array)
&& compareSelector == null
&& Enumerable.From(second).Count() != this.Count())
{
return false;
} return Enumerable.prototype.SequenceEqual.apply(this, arguments);
} ArrayEnumerable.prototype.ToString = function (separator, selector)
{
if (selector != null || !(this.source instanceof Array))
{
return Enumerable.prototype.ToString.apply(this, arguments);
} if (separator == null) separator = "";
return this.source.join(separator);
} ArrayEnumerable.prototype.GetEnumerator = function ()
{
var source = this.source;
var index = 0; return new IEnumerator(
Functions.Blank,
function ()
{
return (index < source.length)
? this.Yield(source[index++])
: false;
},
Functions.Blank);
} // Collections var Dictionary = (function ()
{
// static utility methods
var HasOwnProperty = function (target, key)
{
return Object.prototype.hasOwnProperty.call(target, key);
} var ComputeHashCode = function (obj)
{
if (obj === null) return "null";
if (obj === undefined) return "undefined"; return (typeof obj.toString === Types.Function)
? obj.toString()
: Object.prototype.toString.call(obj);
} // LinkedList for Dictionary
var HashEntry = function (key, value)
{
this.Key = key;
this.Value = value;
this.Prev = null;
this.Next = null;
} var EntryList = function ()
{
this.First = null;
this.Last = null;
}
EntryList.prototype =
{
AddLast: function (entry)
{
if (this.Last != null)
{
this.Last.Next = entry;
entry.Prev = this.Last;
this.Last = entry;
}
else this.First = this.Last = entry;
}, Replace: function (entry, newEntry)
{
if (entry.Prev != null)
{
entry.Prev.Next = newEntry;
newEntry.Prev = entry.Prev;
}
else this.First = newEntry; if (entry.Next != null)
{
entry.Next.Prev = newEntry;
newEntry.Next = entry.Next;
}
else this.Last = newEntry; }, Remove: function (entry)
{
if (entry.Prev != null) entry.Prev.Next = entry.Next;
else this.First = entry.Next; if (entry.Next != null) entry.Next.Prev = entry.Prev;
else this.Last = entry.Prev;
}
} // Overload:function()
// Overload:function(compareSelector)
var Dictionary = function (compareSelector)
{
this.count = 0;
this.entryList = new EntryList();
this.buckets = {}; // as Dictionary<string,List<object>>
this.compareSelector = (compareSelector == null) ? Functions.Identity : compareSelector;
} Dictionary.prototype =
{
Add: function (key, value)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
var entry = new HashEntry(key, value);
if (HasOwnProperty(this.buckets, hash))
{
var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
this.entryList.Replace(array[i], entry);
array[i] = entry;
return;
}
}
array.push(entry);
}
else
{
this.buckets[hash] = [entry];
}
this.count++;
this.entryList.AddLast(entry);
}, Get: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return undefined; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
var entry = array[i];
if (this.compareSelector(entry.Key) === compareKey) return entry.Value;
}
return undefined;
}, Set: function (key, value)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (HasOwnProperty(this.buckets, hash))
{
var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
var newEntry = new HashEntry(key, value);
this.entryList.Replace(array[i], newEntry);
array[i] = newEntry;
return true;
}
}
}
return false;
}, Contains: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return false; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey) return true;
}
return false;
}, Clear: function ()
{
this.count = 0;
this.buckets = {};
this.entryList = new EntryList();
}, Remove: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
this.entryList.Remove(array[i]);
array.splice(i, 1);
if (array.length == 0) delete this.buckets[hash];
this.count--;
return;
}
}
}, Count: function ()
{
return this.count;
}, ToEnumerable: function ()
{
var self = this;
return new Enumerable(function ()
{
var currentEntry; return new IEnumerator(
function () { currentEntry = self.entryList.First },
function ()
{
if (currentEntry != null)
{
var result = { Key: currentEntry.Key, Value: currentEntry.Value };
currentEntry = currentEntry.Next;
return this.Yield(result);
}
return false;
},
Functions.Blank);
});
}
} return Dictionary;
})(); // dictionary = Dictionary<TKey, TValue[]>
var Lookup = function (dictionary)
{
this.Count = function ()
{
return dictionary.Count();
} this.Get = function (key)
{
return Enumerable.From(dictionary.Get(key));
} this.Contains = function (key)
{
return dictionary.Contains(key);
} this.ToEnumerable = function ()
{
return dictionary.ToEnumerable().Select(function (kvp)
{
return new Grouping(kvp.Key, kvp.Value);
});
}
} var Grouping = function (key, elements)
{
this.Key = function ()
{
return key;
} ArrayEnumerable.call(this, elements);
}
Grouping.prototype = new ArrayEnumerable(); // out to global
return Enumerable;
})()}); // binding for jQuery
// toEnumerable / TojQuery (function ($, Enumerable)
{
$.fn.toEnumerable = function ()
{
/// <summary>each contains elements. to Enumerable&lt;jQuery&gt;.</summary>
/// <returns type="Enumerable"></returns>
return Enumerable.From(this).Select(function (e) { return $(e) });
} Enumerable.prototype.TojQuery = function ()
{
/// <summary>Enumerable to jQuery.</summary>
/// <returns type="jQuery"></returns>
return $(this.ToArray());
}
})(jQuery, this.Enumerable || this.jQuery.Enumerable)

linq.js

/*--------------------------------------------------------------------------
* linq.js - LINQ for JavaScript
* ver 2.2.0.2 (Jan. 21th, 2011)
*
* created and maintained by neuecc <ils@neue.cc>
* licensed under Microsoft Public License(Ms-PL)
* http://neue.cc/
* http://linqjs.codeplex.com/
*--------------------------------------------------------------------------*/ Enumerable = (function ()
{
var Enumerable = function (getEnumerator)
{
this.GetEnumerator = getEnumerator;
} // Generator Enumerable.Choice = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments; return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function ()
{
return this.Yield(args[Math.floor(Math.random() * args.length)]);
},
Functions.Blank);
});
} Enumerable.Cycle = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments; return new Enumerable(function ()
{
var index = 0;
return new IEnumerator(
Functions.Blank,
function ()
{
if (index >= args.length) index = 0;
return this.Yield(args[index++]);
},
Functions.Blank);
});
} Enumerable.Empty = function ()
{
return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return false; },
Functions.Blank);
});
} Enumerable.From = function (obj)
{
if (obj == null)
{
return Enumerable.Empty();
}
if (obj instanceof Enumerable)
{
return obj;
}
if (typeof obj == Types.Number || typeof obj == Types.Boolean)
{
return Enumerable.Repeat(obj, 1);
}
if (typeof obj == Types.String)
{
return new Enumerable(function ()
{
var index = 0;
return new IEnumerator(
Functions.Blank,
function ()
{
return (index < obj.length) ? this.Yield(obj.charAt(index++)) : false;
},
Functions.Blank);
});
}
if (typeof obj != Types.Function)
{
// array or array like object
if (typeof obj.length == Types.Number)
{
return new ArrayEnumerable(obj);
} // JScript's IEnumerable
if (!(obj instanceof Object) && Utils.IsIEnumerable(obj))
{
return new Enumerable(function ()
{
var isFirst = true;
var enumerator;
return new IEnumerator(
function () { enumerator = new Enumerator(obj); },
function ()
{
if (isFirst) isFirst = false;
else enumerator.moveNext(); return (enumerator.atEnd()) ? false : this.Yield(enumerator.item());
},
Functions.Blank);
});
}
} // case function/object : Create KeyValuePair[]
return new Enumerable(function ()
{
var array = [];
var index = 0; return new IEnumerator(
function ()
{
for (var key in obj)
{
if (!(obj[key] instanceof Function))
{
array.push({ Key: key, Value: obj[key] });
}
}
},
function ()
{
return (index < array.length)
? this.Yield(array[index++])
: false;
},
Functions.Blank);
});
}, Enumerable.Return = function (element)
{
return Enumerable.Repeat(element, 1);
} // Overload:function(input, pattern)
// Overload:function(input, pattern, flags)
Enumerable.Matches = function (input, pattern, flags)
{
if (flags == null) flags = "";
if (pattern instanceof RegExp)
{
flags += (pattern.ignoreCase) ? "i" : "";
flags += (pattern.multiline) ? "m" : "";
pattern = pattern.source;
}
if (flags.indexOf("g") === -1) flags += "g"; return new Enumerable(function ()
{
var regex;
return new IEnumerator(
function () { regex = new RegExp(pattern, flags) },
function ()
{
var match = regex.exec(input);
return (match) ? this.Yield(match) : false;
},
Functions.Blank);
});
} // Overload:function(start, count)
// Overload:function(start, count, step)
Enumerable.Range = function (start, count, step)
{
if (step == null) step = 1;
return Enumerable.ToInfinity(start, step).Take(count);
} // Overload:function(start, count)
// Overload:function(start, count, step)
Enumerable.RangeDown = function (start, count, step)
{
if (step == null) step = 1;
return Enumerable.ToNegativeInfinity(start, step).Take(count);
} // Overload:function(start, to)
// Overload:function(start, to, step)
Enumerable.RangeTo = function (start, to, step)
{
if (step == null) step = 1;
return (start < to)
? Enumerable.ToInfinity(start, step).TakeWhile(function (i) { return i <= to; })
: Enumerable.ToNegativeInfinity(start, step).TakeWhile(function (i) { return i >= to; })
} // Overload:function(obj)
// Overload:function(obj, num)
Enumerable.Repeat = function (obj, num)
{
if (num != null) return Enumerable.Repeat(obj).Take(num); return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(obj); },
Functions.Blank);
});
} Enumerable.RepeatWithFinalize = function (initializer, finalizer)
{
initializer = Utils.CreateLambda(initializer);
finalizer = Utils.CreateLambda(finalizer); return new Enumerable(function ()
{
var element;
return new IEnumerator(
function () { element = initializer(); },
function () { return this.Yield(element); },
function ()
{
if (element != null)
{
finalizer(element);
element = null;
}
});
});
} // Overload:function(func)
// Overload:function(func, count)
Enumerable.Generate = function (func, count)
{
if (count != null) return Enumerable.Generate(func).Take(count);
func = Utils.CreateLambda(func); return new Enumerable(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(func()); },
Functions.Blank);
});
} // Overload:function()
// Overload:function(start)
// Overload:function(start, step)
Enumerable.ToInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1; return new Enumerable(function ()
{
var value;
return new IEnumerator(
function () { value = start - step },
function () { return this.Yield(value += step); },
Functions.Blank);
});
} // Overload:function()
// Overload:function(start)
// Overload:function(start, step)
Enumerable.ToNegativeInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1; return new Enumerable(function ()
{
var value;
return new IEnumerator(
function () { value = start + step },
function () { return this.Yield(value -= step); },
Functions.Blank);
});
} Enumerable.Unfold = function (seed, func)
{
func = Utils.CreateLambda(func); return new Enumerable(function ()
{
var isFirst = true;
var value;
return new IEnumerator(
Functions.Blank,
function ()
{
if (isFirst)
{
isFirst = false;
value = seed;
return this.Yield(value);
}
value = func(value);
return this.Yield(value);
},
Functions.Blank);
});
} // Extension Methods Enumerable.prototype =
{
/* Projection and Filtering Methods */ // Overload:function(func)
// Overload:function(func, resultSelector<element>)
// Overload:function(func, resultSelector<element, nestLevel>)
CascadeBreadthFirst: function (func, resultSelector)
{
var source = this;
func = Utils.CreateLambda(func);
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumerator;
var nestLevel = 0;
var buffer = []; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (enumerator.MoveNext())
{
buffer.push(enumerator.Current());
return this.Yield(resultSelector(enumerator.Current(), nestLevel));
} var next = Enumerable.From(buffer).SelectMany(function (x) { return func(x); });
if (!next.Any())
{
return false;
}
else
{
nestLevel++;
buffer = [];
Utils.Dispose(enumerator);
enumerator = next.GetEnumerator();
}
}
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(func)
// Overload:function(func, resultSelector<element>)
// Overload:function(func, resultSelector<element, nestLevel>)
CascadeDepthFirst: function (func, resultSelector)
{
var source = this;
func = Utils.CreateLambda(func);
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumeratorStack = [];
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (enumerator.MoveNext())
{
var value = resultSelector(enumerator.Current(), enumeratorStack.length);
enumeratorStack.push(enumerator);
enumerator = Enumerable.From(func(enumerator.Current())).GetEnumerator();
return this.Yield(value);
} if (enumeratorStack.length <= 0) return false;
Utils.Dispose(enumerator);
enumerator = enumeratorStack.pop();
}
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Enumerable.From(enumeratorStack).ForEach(function (s) { s.Dispose(); }) }
});
});
}, Flatten: function ()
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var middleEnumerator = null; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (true)
{
if (middleEnumerator != null)
{
if (middleEnumerator.MoveNext())
{
return this.Yield(middleEnumerator.Current());
}
else
{
middleEnumerator = null;
}
} if (enumerator.MoveNext())
{
if (enumerator.Current() instanceof Array)
{
Utils.Dispose(middleEnumerator);
middleEnumerator = Enumerable.From(enumerator.Current())
.SelectMany(Functions.Identity)
.Flatten()
.GetEnumerator();
continue;
}
else
{
return this.Yield(enumerator.Current());
}
} return false;
}
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Utils.Dispose(middleEnumerator); }
});
});
}, Pairwise: function (selector)
{
var source = this;
selector = Utils.CreateLambda(selector); return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
enumerator.MoveNext();
},
function ()
{
var prev = enumerator.Current();
return (enumerator.MoveNext())
? this.Yield(selector(prev, enumerator.Current()))
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(func)
// Overload:function(seed,func<value,element>)
// Overload:function(seed,func<value,element>,resultSelector)
Scan: function (seed, func, resultSelector)
{
if (resultSelector != null) return this.Scan(seed, func).Select(resultSelector); var isUseSeed;
if (func == null)
{
func = Utils.CreateLambda(seed); // arguments[0]
isUseSeed = false;
}
else
{
func = Utils.CreateLambda(func);
isUseSeed = true;
}
var source = this; return new Enumerable(function ()
{
var enumerator;
var value;
var isFirst = true; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (isFirst)
{
isFirst = false;
if (!isUseSeed)
{
if (enumerator.MoveNext())
{
return this.Yield(value = enumerator.Current());
}
}
else
{
return this.Yield(value = seed);
}
} return (enumerator.MoveNext())
? this.Yield(value = func(value, enumerator.Current()))
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(selector<element>)
// Overload:function(selector<element,index>)
Select: function (selector)
{
var source = this;
selector = Utils.CreateLambda(selector); return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext())
? this.Yield(selector(enumerator.Current(), index++))
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(collectionSelector<element>)
// Overload:function(collectionSelector<element,index>)
// Overload:function(collectionSelector<element>,resultSelector)
// Overload:function(collectionSelector<element,index>,resultSelector)
SelectMany: function (collectionSelector, resultSelector)
{
var source = this;
collectionSelector = Utils.CreateLambda(collectionSelector);
if (resultSelector == null) resultSelector = function (a, b) { return b; }
resultSelector = Utils.CreateLambda(resultSelector); return new Enumerable(function ()
{
var enumerator;
var middleEnumerator = undefined;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (middleEnumerator === undefined)
{
if (!enumerator.MoveNext()) return false;
}
do
{
if (middleEnumerator == null)
{
var middleSeq = collectionSelector(enumerator.Current(), index++);
middleEnumerator = Enumerable.From(middleSeq).GetEnumerator();
}
if (middleEnumerator.MoveNext())
{
return this.Yield(resultSelector(enumerator.Current(), middleEnumerator.Current()));
}
Utils.Dispose(middleEnumerator);
middleEnumerator = null;
} while (enumerator.MoveNext())
return false;
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { Utils.Dispose(middleEnumerator); }
})
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
Where: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (enumerator.MoveNext())
{
if (predicate(enumerator.Current(), index++))
{
return this.Yield(enumerator.Current());
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, OfType: function (type)
{
var typeName;
switch (type)
{
case Number: typeName = Types.Number; break;
case String: typeName = Types.String; break;
case Boolean: typeName = Types.Boolean; break;
case Function: typeName = Types.Function; break;
default: typeName = null; break;
}
return (typeName === null)
? this.Where(function (x) { return x instanceof type })
: this.Where(function (x) { return typeof x === typeName });
}, // Overload:function(second,selector<outer,inner>)
// Overload:function(second,selector<outer,inner,index>)
Zip: function (second, selector)
{
selector = Utils.CreateLambda(selector);
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var index = 0; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = Enumerable.From(second).GetEnumerator();
},
function ()
{
if (firstEnumerator.MoveNext() && secondEnumerator.MoveNext())
{
return this.Yield(selector(firstEnumerator.Current(), secondEnumerator.Current(), index++));
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, /* Join Methods */ // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
// Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
Join: function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
{
outerKeySelector = Utils.CreateLambda(outerKeySelector);
innerKeySelector = Utils.CreateLambda(innerKeySelector);
resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var outerEnumerator;
var lookup;
var innerElements = null;
var innerCount = 0; return new IEnumerator(
function ()
{
outerEnumerator = source.GetEnumerator();
lookup = Enumerable.From(inner).ToLookup(innerKeySelector, Functions.Identity, compareSelector);
},
function ()
{
while (true)
{
if (innerElements != null)
{
var innerElement = innerElements[innerCount++];
if (innerElement !== undefined)
{
return this.Yield(resultSelector(outerEnumerator.Current(), innerElement));
} innerElement = null;
innerCount = 0;
} if (outerEnumerator.MoveNext())
{
var key = outerKeySelector(outerEnumerator.Current());
innerElements = lookup.Get(key).ToArray();
}
else
{
return false;
}
}
},
function () { Utils.Dispose(outerEnumerator); })
});
}, // Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector)
// Overload:function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
GroupJoin: function (inner, outerKeySelector, innerKeySelector, resultSelector, compareSelector)
{
outerKeySelector = Utils.CreateLambda(outerKeySelector);
innerKeySelector = Utils.CreateLambda(innerKeySelector);
resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator = source.GetEnumerator();
var lookup = null; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
lookup = Enumerable.From(inner).ToLookup(innerKeySelector, Functions.Identity, compareSelector);
},
function ()
{
if (enumerator.MoveNext())
{
var innerElement = lookup.Get(outerKeySelector(enumerator.Current()));
return this.Yield(resultSelector(enumerator.Current(), innerElement));
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, /* Set Methods */ All: function (predicate)
{
predicate = Utils.CreateLambda(predicate); var result = true;
this.ForEach(function (x)
{
if (!predicate(x))
{
result = false;
return false; // break
}
});
return result;
}, // Overload:function()
// Overload:function(predicate)
Any: function (predicate)
{
predicate = Utils.CreateLambda(predicate); var enumerator = this.GetEnumerator();
try
{
if (arguments.length == 0) return enumerator.MoveNext(); // case:function() while (enumerator.MoveNext()) // case:function(predicate)
{
if (predicate(enumerator.Current())) return true;
}
return false;
}
finally { Utils.Dispose(enumerator); }
}, Concat: function (second)
{
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator; return new IEnumerator(
function () { firstEnumerator = source.GetEnumerator(); },
function ()
{
if (secondEnumerator == null)
{
if (firstEnumerator.MoveNext()) return this.Yield(firstEnumerator.Current());
secondEnumerator = Enumerable.From(second).GetEnumerator();
}
if (secondEnumerator.MoveNext()) return this.Yield(secondEnumerator.Current());
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, Insert: function (index, second)
{
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var count = 0;
var isEnumerated = false; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = Enumerable.From(second).GetEnumerator();
},
function ()
{
if (count == index && secondEnumerator.MoveNext())
{
isEnumerated = true;
return this.Yield(secondEnumerator.Current());
}
if (firstEnumerator.MoveNext())
{
count++;
return this.Yield(firstEnumerator.Current());
}
if (!isEnumerated && secondEnumerator.MoveNext())
{
return this.Yield(secondEnumerator.Current());
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, Alternate: function (value)
{
value = Enumerable.Return(value);
return this.SelectMany(function (elem)
{
return Enumerable.Return(elem).Concat(value);
}).TakeExceptLast();
}, // Overload:function(value)
// Overload:function(value, compareSelector)
Contains: function (value, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var enumerator = this.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
if (compareSelector(enumerator.Current()) === value) return true;
}
return false;
}
finally { Utils.Dispose(enumerator) }
}, DefaultIfEmpty: function (defaultValue)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var isFirst = true; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (enumerator.MoveNext())
{
isFirst = false;
return this.Yield(enumerator.Current());
}
else if (isFirst)
{
isFirst = false;
return this.Yield(defaultValue);
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function()
// Overload:function(compareSelector)
Distinct: function (compareSelector)
{
return this.Except(Enumerable.Empty(), compareSelector);
}, // Overload:function(second)
// Overload:function(second, compareSelector)
Except: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator;
var keys; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
Enumerable.From(second).ForEach(function (key) { keys.Add(key); });
},
function ()
{
while (enumerator.MoveNext())
{
var current = enumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(second)
// Overload:function(second, compareSelector)
Intersect: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var enumerator;
var keys;
var outs; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator(); keys = new Dictionary(compareSelector);
Enumerable.From(second).ForEach(function (key) { keys.Add(key); });
outs = new Dictionary(compareSelector);
},
function ()
{
while (enumerator.MoveNext())
{
var current = enumerator.Current();
if (!outs.Contains(current) && keys.Contains(current))
{
outs.Add(current);
return this.Yield(current);
}
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(second)
// Overload:function(second, compareSelector)
SequenceEqual: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector); var firstEnumerator = this.GetEnumerator();
try
{
var secondEnumerator = Enumerable.From(second).GetEnumerator();
try
{
while (firstEnumerator.MoveNext())
{
if (!secondEnumerator.MoveNext()
|| compareSelector(firstEnumerator.Current()) !== compareSelector(secondEnumerator.Current()))
{
return false;
}
} if (secondEnumerator.MoveNext()) return false;
return true;
}
finally { Utils.Dispose(secondEnumerator); }
}
finally { Utils.Dispose(firstEnumerator); }
}, Union: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this; return new Enumerable(function ()
{
var firstEnumerator;
var secondEnumerator;
var keys; return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
},
function ()
{
var current;
if (secondEnumerator === undefined)
{
while (firstEnumerator.MoveNext())
{
current = firstEnumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
secondEnumerator = Enumerable.From(second).GetEnumerator();
}
while (secondEnumerator.MoveNext())
{
current = secondEnumerator.Current();
if (!keys.Contains(current))
{
keys.Add(current);
return this.Yield(current);
}
}
return false;
},
function ()
{
try { Utils.Dispose(firstEnumerator); }
finally { Utils.Dispose(secondEnumerator); }
})
});
}, /* Ordering Methods */ OrderBy: function (keySelector)
{
return new OrderedEnumerable(this, keySelector, false);
}, OrderByDescending: function (keySelector)
{
return new OrderedEnumerable(this, keySelector, true);
}, Reverse: function ()
{
var source = this; return new Enumerable(function ()
{
var buffer;
var index; return new IEnumerator(
function ()
{
buffer = source.ToArray();
index = buffer.length;
},
function ()
{
return (index > 0)
? this.Yield(buffer[--index])
: false;
},
Functions.Blank)
});
}, Shuffle: function ()
{
var source = this; return new Enumerable(function ()
{
var buffer; return new IEnumerator(
function () { buffer = source.ToArray(); },
function ()
{
if (buffer.length > 0)
{
var i = Math.floor(Math.random() * buffer.length);
return this.Yield(buffer.splice(i, 1)[0]);
}
return false;
},
Functions.Blank)
});
}, /* Grouping Methods */ // Overload:function(keySelector)
// Overload:function(keySelector,elementSelector)
// Overload:function(keySelector,elementSelector,resultSelector)
// Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
GroupBy: function (keySelector, elementSelector, resultSelector, compareSelector)
{
var source = this;
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
if (resultSelector != null) resultSelector = Utils.CreateLambda(resultSelector);
compareSelector = Utils.CreateLambda(compareSelector); return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = source.ToLookup(keySelector, elementSelector, compareSelector)
.ToEnumerable()
.GetEnumerator();
},
function ()
{
while (enumerator.MoveNext())
{
return (resultSelector == null)
? this.Yield(enumerator.Current())
: this.Yield(resultSelector(enumerator.Current().Key(), enumerator.Current()));
}
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(keySelector)
// Overload:function(keySelector,elementSelector)
// Overload:function(keySelector,elementSelector,resultSelector)
// Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
PartitionBy: function (keySelector, elementSelector, resultSelector, compareSelector)
{ var source = this;
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector);
var hasResultSelector;
if (resultSelector == null)
{
hasResultSelector = false;
resultSelector = function (key, group) { return new Grouping(key, group) }
}
else
{
hasResultSelector = true;
resultSelector = Utils.CreateLambda(resultSelector);
} return new Enumerable(function ()
{
var enumerator;
var key;
var compareKey;
var group = []; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
if (enumerator.MoveNext())
{
key = keySelector(enumerator.Current());
compareKey = compareSelector(key);
group.push(elementSelector(enumerator.Current()));
}
},
function ()
{
var hasNext;
while ((hasNext = enumerator.MoveNext()) == true)
{
if (compareKey === compareSelector(keySelector(enumerator.Current())))
{
group.push(elementSelector(enumerator.Current()));
}
else break;
} if (group.length > 0)
{
var result = (hasResultSelector)
? resultSelector(key, Enumerable.From(group))
: resultSelector(key, group);
if (hasNext)
{
key = keySelector(enumerator.Current());
compareKey = compareSelector(key);
group = [elementSelector(enumerator.Current())];
}
else group = []; return this.Yield(result);
} return false;
},
function () { Utils.Dispose(enumerator); })
});
}, BufferWithCount: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
var array = [];
var index = 0;
while (enumerator.MoveNext())
{
array.push(enumerator.Current());
if (++index >= count) return this.Yield(array);
}
if (array.length > 0) return this.Yield(array);
return false;
},
function () { Utils.Dispose(enumerator); })
});
}, /* Aggregate Methods */ // Overload:function(func)
// Overload:function(seed,func)
// Overload:function(seed,func,resultSelector)
Aggregate: function (seed, func, resultSelector)
{
return this.Scan(seed, func, resultSelector).Last();
}, // Overload:function()
// Overload:function(selector)
Average: function (selector)
{
selector = Utils.CreateLambda(selector); var sum = 0;
var count = 0;
this.ForEach(function (x)
{
sum += selector(x);
++count;
}); return sum / count;
}, // Overload:function()
// Overload:function(predicate)
Count: function (predicate)
{
predicate = (predicate == null) ? Functions.True : Utils.CreateLambda(predicate); var count = 0;
this.ForEach(function (x, i)
{
if (predicate(x, i)) ++count;
});
return count;
}, // Overload:function()
// Overload:function(selector)
Max: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(function (a, b) { return (a > b) ? a : b; });
}, // Overload:function()
// Overload:function(selector)
Min: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(function (a, b) { return (a < b) ? a : b; });
}, MaxBy: function (keySelector)
{
keySelector = Utils.CreateLambda(keySelector);
return this.Aggregate(function (a, b) { return (keySelector(a) > keySelector(b)) ? a : b });
}, MinBy: function (keySelector)
{
keySelector = Utils.CreateLambda(keySelector);
return this.Aggregate(function (a, b) { return (keySelector(a) < keySelector(b)) ? a : b });
}, // Overload:function()
// Overload:function(selector)
Sum: function (selector)
{
if (selector == null) selector = Functions.Identity;
return this.Select(selector).Aggregate(0, function (a, b) { return a + b; });
}, /* Paging Methods */ ElementAt: function (index)
{
var value;
var found = false;
this.ForEach(function (x, i)
{
if (i == index)
{
value = x;
found = true;
return false;
}
}); if (!found) throw new Error("index is less than 0 or greater than or equal to the number of elements in source.");
return value;
}, ElementAtOrDefault: function (index, defaultValue)
{
var value;
var found = false;
this.ForEach(function (x, i)
{
if (i == index)
{
value = x;
found = true;
return false;
}
}); return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
First: function (predicate)
{
if (predicate != null) return this.Where(predicate).First(); var value;
var found = false;
this.ForEach(function (x)
{
value = x;
found = true;
return false;
}); if (!found) throw new Error("First:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
FirstOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).FirstOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
value = x;
found = true;
return false;
});
return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
Last: function (predicate)
{
if (predicate != null) return this.Where(predicate).Last(); var value;
var found = false;
this.ForEach(function (x)
{
found = true;
value = x;
}); if (!found) throw new Error("Last:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
LastOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).LastOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
found = true;
value = x;
});
return (!found) ? defaultValue : value;
}, // Overload:function()
// Overload:function(predicate)
Single: function (predicate)
{
if (predicate != null) return this.Where(predicate).Single(); var value;
var found = false;
this.ForEach(function (x)
{
if (!found)
{
found = true;
value = x;
}
else throw new Error("Single:sequence contains more than one element.");
}); if (!found) throw new Error("Single:No element satisfies the condition.");
return value;
}, // Overload:function(defaultValue)
// Overload:function(defaultValue,predicate)
SingleOrDefault: function (defaultValue, predicate)
{
if (predicate != null) return this.Where(predicate).SingleOrDefault(defaultValue); var value;
var found = false;
this.ForEach(function (x)
{
if (!found)
{
found = true;
value = x;
}
else throw new Error("Single:sequence contains more than one element.");
}); return (!found) ? defaultValue : value;
}, Skip: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
while (index++ < count && enumerator.MoveNext()) { };
},
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
SkipWhile: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0;
var isSkipEnd = false; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (!isSkipEnd)
{
if (enumerator.MoveNext())
{
if (!predicate(enumerator.Current(), index++))
{
isSkipEnd = true;
return this.Yield(enumerator.Current());
}
continue;
}
else return false;
} return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false; },
function () { Utils.Dispose(enumerator); });
});
}, Take: function (count)
{
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (index++ < count && enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); }
)
});
}, // Overload:function(predicate<element>)
// Overload:function(predicate<element,index>)
TakeWhile: function (predicate)
{
predicate = Utils.CreateLambda(predicate);
var source = this; return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext() && predicate(enumerator.Current(), index++))
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function()
// Overload:function(count)
TakeExceptLast: function (count)
{
if (count == null) count = 1;
var source = this; return new Enumerable(function ()
{
if (count <= 0) return source.GetEnumerator(); // do nothing var enumerator;
var q = []; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
while (enumerator.MoveNext())
{
if (q.length == count)
{
q.push(enumerator.Current());
return this.Yield(q.shift());
}
q.push(enumerator.Current());
}
return false;
},
function () { Utils.Dispose(enumerator); });
});
}, TakeFromLast: function (count)
{
if (count <= 0 || count == null) return Enumerable.Empty();
var source = this; return new Enumerable(function ()
{
var sourceEnumerator;
var enumerator;
var q = []; return new IEnumerator(
function () { sourceEnumerator = source.GetEnumerator(); },
function ()
{
while (sourceEnumerator.MoveNext())
{
if (q.length == count) q.shift()
q.push(sourceEnumerator.Current());
}
if (enumerator == null)
{
enumerator = Enumerable.From(q).GetEnumerator();
}
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); });
});
}, IndexOf: function (item)
{
var found = null;
this.ForEach(function (x, i)
{
if (x === item)
{
found = i;
return true;
}
}); return (found !== null) ? found : -1;
}, LastIndexOf: function (item)
{
var result = -1;
this.ForEach(function (x, i)
{
if (x === item) result = i;
}); return result;
}, /* Convert Methods */ ToArray: function ()
{
var array = [];
this.ForEach(function (x) { array.push(x) });
return array;
}, // Overload:function(keySelector)
// Overload:function(keySelector, elementSelector)
// Overload:function(keySelector, elementSelector, compareSelector)
ToLookup: function (keySelector, elementSelector, compareSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector); var dict = new Dictionary(compareSelector);
this.ForEach(function (x)
{
var key = keySelector(x);
var element = elementSelector(x); var array = dict.Get(key);
if (array !== undefined) array.push(element);
else dict.Add(key, [element]);
});
return new Lookup(dict);
}, ToObject: function (keySelector, elementSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector); var obj = {};
this.ForEach(function (x)
{
obj[keySelector(x)] = elementSelector(x);
});
return obj;
}, // Overload:function(keySelector, elementSelector)
// Overload:function(keySelector, elementSelector, compareSelector)
ToDictionary: function (keySelector, elementSelector, compareSelector)
{
keySelector = Utils.CreateLambda(keySelector);
elementSelector = Utils.CreateLambda(elementSelector);
compareSelector = Utils.CreateLambda(compareSelector); var dict = new Dictionary(compareSelector);
this.ForEach(function (x)
{
dict.Add(keySelector(x), elementSelector(x));
});
return dict;
}, // Overload:function()
// Overload:function(replacer)
// Overload:function(replacer, space)
ToJSON: function (replacer, space)
{
return JSON.stringify(this.ToArray(), replacer, space);
}, // Overload:function()
// Overload:function(separator)
// Overload:function(separator,selector)
ToString: function (separator, selector)
{
if (separator == null) separator = "";
if (selector == null) selector = Functions.Identity; return this.Select(selector).ToArray().join(separator);
}, /* Action Methods */ // Overload:function(action<element>)
// Overload:function(action<element,index>)
Do: function (action)
{
var source = this;
action = Utils.CreateLambda(action); return new Enumerable(function ()
{
var enumerator;
var index = 0; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
if (enumerator.MoveNext())
{
action(enumerator.Current(), index++);
return this.Yield(enumerator.Current());
}
return false;
},
function () { Utils.Dispose(enumerator); });
});
}, // Overload:function(action<element>)
// Overload:function(action<element,index>)
// Overload:function(func<element,bool>)
// Overload:function(func<element,index,bool>)
ForEach: function (action)
{
action = Utils.CreateLambda(action); var index = 0;
var enumerator = this.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
if (action(enumerator.Current(), index++) === false) break;
}
}
finally { Utils.Dispose(enumerator); }
}, // Overload:function()
// Overload:function(separator)
// Overload:function(separator,selector)
Write: function (separator, selector)
{
if (separator == null) separator = "";
selector = Utils.CreateLambda(selector); var isFirst = true;
this.ForEach(function (item)
{
if (isFirst) isFirst = false;
else document.write(separator);
document.write(selector(item));
});
}, // Overload:function()
// Overload:function(selector)
WriteLine: function (selector)
{
selector = Utils.CreateLambda(selector); this.ForEach(function (item)
{
document.write(selector(item));
document.write("<br />");
});
}, Force: function ()
{
var enumerator = this.GetEnumerator(); try { while (enumerator.MoveNext()) { } }
finally { Utils.Dispose(enumerator); }
}, /* Functional Methods */ Let: function (func)
{
func = Utils.CreateLambda(func);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function ()
{
enumerator = Enumerable.From(func(source)).GetEnumerator();
},
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function () { Utils.Dispose(enumerator); })
});
}, Share: function ()
{
var source = this;
var sharedEnumerator; return new Enumerable(function ()
{
return new IEnumerator(
function ()
{
if (sharedEnumerator == null)
{
sharedEnumerator = source.GetEnumerator();
}
},
function ()
{
return (sharedEnumerator.MoveNext())
? this.Yield(sharedEnumerator.Current())
: false;
},
Functions.Blank
)
});
}, MemoizeAll: function ()
{
var source = this;
var cache;
var enumerator; return new Enumerable(function ()
{
var index = -1; return new IEnumerator(
function ()
{
if (enumerator == null)
{
enumerator = source.GetEnumerator();
cache = [];
}
},
function ()
{
index++;
if (cache.length <= index)
{
return (enumerator.MoveNext())
? this.Yield(cache[index] = enumerator.Current())
: false;
} return this.Yield(cache[index]);
},
Functions.Blank
)
});
}, /* Error Handling Methods */ Catch: function (handler)
{
handler = Utils.CreateLambda(handler);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
try
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
}
catch (e)
{
handler(e);
return false;
}
},
function () { Utils.Dispose(enumerator); });
});
}, Finally: function (finallyAction)
{
finallyAction = Utils.CreateLambda(finallyAction);
var source = this; return new Enumerable(function ()
{
var enumerator; return new IEnumerator(
function () { enumerator = source.GetEnumerator(); },
function ()
{
return (enumerator.MoveNext())
? this.Yield(enumerator.Current())
: false;
},
function ()
{
try { Utils.Dispose(enumerator); }
finally { finallyAction(); }
});
});
}, /* For Debug Methods */ // Overload:function()
// Overload:function(message)
// Overload:function(message,selector)
Trace: function (message, selector)
{
if (message == null) message = "Trace";
selector = Utils.CreateLambda(selector); return this.Do(function (item)
{
console.log(message, ":", selector(item));
});
}
} // private // static functions
var Functions =
{
Identity: function (x) { return x; },
True: function () { return true; },
Blank: function () { }
} // static const
var Types =
{
Boolean: typeof true,
Number: typeof 0,
String: typeof "",
Object: typeof {},
Undefined: typeof undefined,
Function: typeof function () { }
} // static utility methods
var Utils =
{
// Create anonymous function from lambda expression string
CreateLambda: function (expression)
{
if (expression == null) return Functions.Identity;
if (typeof expression == Types.String)
{
if (expression == "")
{
return Functions.Identity;
}
else if (expression.indexOf("=>") == -1)
{
return new Function("$,$$,$$$,$$$$", "return " + expression);
}
else
{
var expr = expression.match(/^[(\s]*([^()]*?)[)\s]*=>(.*)/);
return new Function(expr[1], "return " + expr[2]);
}
}
return expression;
}, IsIEnumerable: function (obj)
{
if (typeof Enumerator != Types.Undefined)
{
try
{
new Enumerator(obj);
return true;
}
catch (e) { }
}
return false;
}, Compare: function (a, b)
{
return (a === b) ? 0
: (a > b) ? 1
: -1;
}, Dispose: function (obj)
{
if (obj != null) obj.Dispose();
}
} // IEnumerator State
var State = { Before: 0, Running: 1, After: 2 } // name "Enumerator" is conflict JScript's "Enumerator"
var IEnumerator = function (initialize, tryGetNext, dispose)
{
var yielder = new Yielder();
var state = State.Before; this.Current = yielder.Current;
this.MoveNext = function ()
{
try
{
switch (state)
{
case State.Before:
state = State.Running;
initialize(); // fall through
case State.Running:
if (tryGetNext.apply(yielder))
{
return true;
}
else
{
this.Dispose();
return false;
}
case State.After:
return false;
}
}
catch (e)
{
this.Dispose();
throw e;
}
}
this.Dispose = function ()
{
if (state != State.Running) return; try { dispose(); }
finally { state = State.After; }
}
} // for tryGetNext
var Yielder = function ()
{
var current = null;
this.Current = function () { return current; }
this.Yield = function (value)
{
current = value;
return true;
}
} // for OrderBy/ThenBy var OrderedEnumerable = function (source, keySelector, descending, parent)
{
this.source = source;
this.keySelector = Utils.CreateLambda(keySelector);
this.descending = descending;
this.parent = parent;
}
OrderedEnumerable.prototype = new Enumerable(); OrderedEnumerable.prototype.CreateOrderedEnumerable = function (keySelector, descending)
{
return new OrderedEnumerable(this.source, keySelector, descending, this);
} OrderedEnumerable.prototype.ThenBy = function (keySelector)
{
return this.CreateOrderedEnumerable(keySelector, false);
} OrderedEnumerable.prototype.ThenByDescending = function (keySelector)
{
return this.CreateOrderedEnumerable(keySelector, true);
} OrderedEnumerable.prototype.GetEnumerator = function ()
{
var self = this;
var buffer;
var indexes;
var index = 0; return new IEnumerator(
function ()
{
buffer = [];
indexes = [];
self.source.ForEach(function (item, index)
{
buffer.push(item);
indexes.push(index);
});
var sortContext = SortContext.Create(self, null);
sortContext.GenerateKeys(buffer); indexes.sort(function (a, b) { return sortContext.Compare(a, b); });
},
function ()
{
return (index < indexes.length)
? this.Yield(buffer[indexes[index++]])
: false;
},
Functions.Blank
)
} var SortContext = function (keySelector, descending, child)
{
this.keySelector = keySelector;
this.descending = descending;
this.child = child;
this.keys = null;
} SortContext.Create = function (orderedEnumerable, currentContext)
{
var context = new SortContext(orderedEnumerable.keySelector, orderedEnumerable.descending, currentContext);
if (orderedEnumerable.parent != null) return SortContext.Create(orderedEnumerable.parent, context);
return context;
} SortContext.prototype.GenerateKeys = function (source)
{
var len = source.length;
var keySelector = this.keySelector;
var keys = new Array(len);
for (var i = 0; i < len; i++) keys[i] = keySelector(source[i]);
this.keys = keys; if (this.child != null) this.child.GenerateKeys(source);
} SortContext.prototype.Compare = function (index1, index2)
{
var comparison = Utils.Compare(this.keys[index1], this.keys[index2]); if (comparison == 0)
{
if (this.child != null) return this.child.Compare(index1, index2)
comparison = Utils.Compare(index1, index2);
} return (this.descending) ? -comparison : comparison;
} // optimize array or arraylike object var ArrayEnumerable = function (source)
{
this.source = source;
}
ArrayEnumerable.prototype = new Enumerable(); ArrayEnumerable.prototype.Any = function (predicate)
{
return (predicate == null)
? (this.source.length > 0)
: Enumerable.prototype.Any.apply(this, arguments);
} ArrayEnumerable.prototype.Count = function (predicate)
{
return (predicate == null)
? this.source.length
: Enumerable.prototype.Count.apply(this, arguments);
} ArrayEnumerable.prototype.ElementAt = function (index)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: Enumerable.prototype.ElementAt.apply(this, arguments);
} ArrayEnumerable.prototype.ElementAtOrDefault = function (index, defaultValue)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: defaultValue;
} ArrayEnumerable.prototype.First = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[0]
: Enumerable.prototype.First.apply(this, arguments);
} ArrayEnumerable.prototype.FirstOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return Enumerable.prototype.FirstOrDefault.apply(this, arguments);
} return this.source.length > 0 ? this.source[0] : defaultValue;
} ArrayEnumerable.prototype.Last = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[this.source.length - 1]
: Enumerable.prototype.Last.apply(this, arguments);
} ArrayEnumerable.prototype.LastOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return Enumerable.prototype.LastOrDefault.apply(this, arguments);
} return this.source.length > 0 ? this.source[this.source.length - 1] : defaultValue;
} ArrayEnumerable.prototype.Skip = function (count)
{
var source = this.source; return new Enumerable(function ()
{
var index; return new IEnumerator(
function () { index = (count < 0) ? 0 : count },
function ()
{
return (index < source.length)
? this.Yield(source[index++])
: false;
},
Functions.Blank);
});
}; ArrayEnumerable.prototype.TakeExceptLast = function (count)
{
if (count == null) count = 1;
return this.Take(this.source.length - count);
} ArrayEnumerable.prototype.TakeFromLast = function (count)
{
return this.Skip(this.source.length - count);
} ArrayEnumerable.prototype.Reverse = function ()
{
var source = this.source; return new Enumerable(function ()
{
var index; return new IEnumerator(
function ()
{
index = source.length;
},
function ()
{
return (index > 0)
? this.Yield(source[--index])
: false;
},
Functions.Blank)
});
} ArrayEnumerable.prototype.SequenceEqual = function (second, compareSelector)
{
if ((second instanceof ArrayEnumerable || second instanceof Array)
&& compareSelector == null
&& Enumerable.From(second).Count() != this.Count())
{
return false;
} return Enumerable.prototype.SequenceEqual.apply(this, arguments);
} ArrayEnumerable.prototype.ToString = function (separator, selector)
{
if (selector != null || !(this.source instanceof Array))
{
return Enumerable.prototype.ToString.apply(this, arguments);
} if (separator == null) separator = "";
return this.source.join(separator);
} ArrayEnumerable.prototype.GetEnumerator = function ()
{
var source = this.source;
var index = 0; return new IEnumerator(
Functions.Blank,
function ()
{
return (index < source.length)
? this.Yield(source[index++])
: false;
},
Functions.Blank);
} // Collections var Dictionary = (function ()
{
// static utility methods
var HasOwnProperty = function (target, key)
{
return Object.prototype.hasOwnProperty.call(target, key);
} var ComputeHashCode = function (obj)
{
if (obj === null) return "null";
if (obj === undefined) return "undefined"; return (typeof obj.toString === Types.Function)
? obj.toString()
: Object.prototype.toString.call(obj);
} // LinkedList for Dictionary
var HashEntry = function (key, value)
{
this.Key = key;
this.Value = value;
this.Prev = null;
this.Next = null;
} var EntryList = function ()
{
this.First = null;
this.Last = null;
}
EntryList.prototype =
{
AddLast: function (entry)
{
if (this.Last != null)
{
this.Last.Next = entry;
entry.Prev = this.Last;
this.Last = entry;
}
else this.First = this.Last = entry;
}, Replace: function (entry, newEntry)
{
if (entry.Prev != null)
{
entry.Prev.Next = newEntry;
newEntry.Prev = entry.Prev;
}
else this.First = newEntry; if (entry.Next != null)
{
entry.Next.Prev = newEntry;
newEntry.Next = entry.Next;
}
else this.Last = newEntry; }, Remove: function (entry)
{
if (entry.Prev != null) entry.Prev.Next = entry.Next;
else this.First = entry.Next; if (entry.Next != null) entry.Next.Prev = entry.Prev;
else this.Last = entry.Prev;
}
} // Overload:function()
// Overload:function(compareSelector)
var Dictionary = function (compareSelector)
{
this.count = 0;
this.entryList = new EntryList();
this.buckets = {}; // as Dictionary<string,List<object>>
this.compareSelector = (compareSelector == null) ? Functions.Identity : compareSelector;
} Dictionary.prototype =
{
Add: function (key, value)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
var entry = new HashEntry(key, value);
if (HasOwnProperty(this.buckets, hash))
{
var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
this.entryList.Replace(array[i], entry);
array[i] = entry;
return;
}
}
array.push(entry);
}
else
{
this.buckets[hash] = [entry];
}
this.count++;
this.entryList.AddLast(entry);
}, Get: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return undefined; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
var entry = array[i];
if (this.compareSelector(entry.Key) === compareKey) return entry.Value;
}
return undefined;
}, Set: function (key, value)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (HasOwnProperty(this.buckets, hash))
{
var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
var newEntry = new HashEntry(key, value);
this.entryList.Replace(array[i], newEntry);
array[i] = newEntry;
return true;
}
}
}
return false;
}, Contains: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return false; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey) return true;
}
return false;
}, Clear: function ()
{
this.count = 0;
this.buckets = {};
this.entryList = new EntryList();
}, Remove: function (key)
{
var compareKey = this.compareSelector(key);
var hash = ComputeHashCode(compareKey);
if (!HasOwnProperty(this.buckets, hash)) return; var array = this.buckets[hash];
for (var i = 0; i < array.length; i++)
{
if (this.compareSelector(array[i].Key) === compareKey)
{
this.entryList.Remove(array[i]);
array.splice(i, 1);
if (array.length == 0) delete this.buckets[hash];
this.count--;
return;
}
}
}, Count: function ()
{
return this.count;
}, ToEnumerable: function ()
{
var self = this;
return new Enumerable(function ()
{
var currentEntry; return new IEnumerator(
function () { currentEntry = self.entryList.First },
function ()
{
if (currentEntry != null)
{
var result = { Key: currentEntry.Key, Value: currentEntry.Value };
currentEntry = currentEntry.Next;
return this.Yield(result);
}
return false;
},
Functions.Blank);
});
}
} return Dictionary;
})(); // dictionary = Dictionary<TKey, TValue[]>
var Lookup = function (dictionary)
{
this.Count = function ()
{
return dictionary.Count();
} this.Get = function (key)
{
return Enumerable.From(dictionary.Get(key));
} this.Contains = function (key)
{
return dictionary.Contains(key);
} this.ToEnumerable = function ()
{
return dictionary.ToEnumerable().Select(function (kvp)
{
return new Grouping(kvp.Key, kvp.Value);
});
}
} var Grouping = function (key, elements)
{
this.Key = function ()
{
return key;
} ArrayEnumerable.call(this, elements);
}
Grouping.prototype = new ArrayEnumerable(); // out to global
return Enumerable;
})()

自己备着

js 对json数据进行检索 插件 linq.js的更多相关文章

  1. js读取json数据(php传值给js)

    <?php $array =array('fds','fdsa','fdsafasd');  // json_encode($array); ?> <html> <hea ...

  2. js声明json数据,打印json数据,遍历json数据

    1.js声明json数据: 2.打印json数据: 3.遍历json数据 //声明JSON var json = {}; json.a = 1; //第一种赋值方式(仿对象型) json['b'] = ...

  3. JS解析json数据并将json字符串转化为数组的实现方法

    json数据在ajax实现异步交互时起到了很重要的作用,他可以返回请求的数据,然后利用客户端的js进行解析,这一点体现出js的强大,本文介绍JS解析json数据并将json字符串转化为数组的实现方法, ...

  4. JS解析json数据

    JS解析json数据(如何将json字符串转化为数组) 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN&q ...

  5. 初探原生js根据json数据动态创建table

    初探原生js根据json数据动态创建table 小生以实习生的职位进入了一家非纯软件的公司做asp.net开发,大半个月下来发现公司里居然没有前端工程师,这令我很诧异,跟着公司做项目,发现前端后台没有 ...

  6. js处理json数据,java处理json数据

    一.js处理json数据 处理办法之一是把本机json数据或远程返回json数据用eval函数,使之变成DOM对象. 例如: var people = { "programmers" ...

  7. js中json数据简单处理(JSON.parse()和js中嵌套html)

    js中json数据简单处理(JSON.parse()和js中嵌套html) 一.总结 1.html中嵌套js:<script>js代码</script> 2.js中嵌套html ...

  8. js声明json数据,打印json数据,遍历json数据,转换json数据为数组

    1.js声明json数据: 2.打印json数据: 3.遍历json数据: 4.转换json数据为数组; //声明JSON var json = {}; json.a = 1; //第一种赋值方式(仿 ...

  9. JS解析Json 数据并跳转到一个新页面,取消A 标签跳转

    JS解析Json 数据并跳转到一个新页面,代码如下 $.getJSON("http://api.cn.abb.com/common/api/staff/employee/" + o ...

随机推荐

  1. 【转载】在python的class中的,self到底是什么?

    在python的class中的,self到底是什么?   答案:self可以理解为一个字典变量,内部存的就是对象的数据属性.如:{'name':'zhang','age':'18'}就是这些. 注意只 ...

  2. 面向对象——python核心编程第二版

    类与实例 类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中所定义的对象的具体信息. class MyData(object): pass >>& ...

  3. 拉勾、Boss直聘、内推、100offer

    BOSS直聘 拉勾.Boss直聘.内推.100offer  

  4. Centos 7 进入单用户模式更改root密码方法

    进入单用户模式的方法 方法一: 1.开机进入grub菜单的时候上下选择,按e编辑. 到linux16所在行的最后面. ro 只读文件系统 biosdevname=0 戴尔的服务器需要设置 net.if ...

  5. shell基础之for循环语句

    For语句 格式:for name [ [ in [ word ... ] ] ; ] do list ; done for 变量名 in 取值列表; do 命令 done 或者 for 变量名 in ...

  6. centos下安装visual studio code-(来自官网)

    (https://code.visualstudio.com/docs/setup/linux) Running VS Code on Linux Installation 安装完成后可执行:$cod ...

  7. IDEA 2019.2.4 破解安装教程

    将下载的 IDEA 压缩包解压,找到 idealIU-2019.2.4.exe 安装文件,然后双击进行安装 安装完后不要运行,打开解压包中破解补丁与激活码文件夹,找到 jetbrains-agent. ...

  8. Java安全之Cas反序列化漏洞分析

    Java安全之Cas反序列化漏洞分析 0x00 前言 某次项目中遇到Cas,以前没接触过,借此机会学习一波. 0x01 Cas 简介 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用 ...

  9. OpenResty搭建高性能服务端

    OpenResty搭建高性能服务端   Socket编程 Linux Socket编程领域为了处理大量连接请求场景,需要使用非阻塞I/O和复用,select.poll.epoll是Linux API提 ...

  10. MindSpore模型精度调优实践

    MindSpore模型精度调优实践 引论:在模型的开发过程中,精度达不到预期常常让人头疼.为了帮助用户解决模型调试调优的问题,为MindSpore量身定做了可视化调试调优组件:MindInsight. ...