1 Star 0 Fork 41

leoasc/JsonSql.js

forked from @HuangBingGui/JsonSql.js 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
JsonSql.js 88.44 KB
一键复制 编辑 原始数据 按行查看 历史
@HuangBingGui 提交于 2020-03-27 09:55 . update JsonSql.js.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804
/*--------------------------------------------------------------------------
* JsonSql.js - JsonSql for JavaScript
* ver 3.0.0.0 (2020-03-20)
* ver 3.1.0.0 (2020-03-23)
*
* created and maintained by huangbinggui
* https://gitee.com/JeeHuangBingGui/JsonSql
*--------------------------------------------------------------------------*/
//例子:https://gitee.com/JeeHuangBingGui/JsonSql/blob/master/JsonSql_Sample.txt
$JsonSql = function (obj){
return JsonSql.Sql(obj).ToJSON();
};
$JsonSqlTo = function (obj){
return JsonSql.Sql(obj);
};
$JsonSqlToJson = function (obj){
return JsonSql.Sql(obj).ToJSON();
};
$JsonSqlToArray = function (obj){
return JsonSql.Sql(obj).ToArray();
};
$JsonSqlToString = function (obj){
return JsonSql.Sql(obj).ToString();
};
$JsonSqlToDictionary= function (obj){
return JsonSql.Sql(obj).ToDictionary();
};
$JsonSqlToObject= function (obj){
return JsonSql.Sql(obj).ToObject();
};
$JsonSqlToLookup= function (obj){
return JsonSql.Sql(obj).ToLookup();
};
JsonSql = (function ()
{
var JsonSql = function (getEnumerator)
{
this.GetEnumerator = getEnumerator;
}
// Generator
JsonSql.Choice = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments;
return new JsonSql(function ()
{
return new IEnumerator(
Functions.Blank,
function ()
{
return this.Yield(args[Math.floor(Math.random() * args.length)]);
},
Functions.Blank);
});
}
JsonSql.Cycle = function () // variable argument
{
var args = (arguments[0] instanceof Array) ? arguments[0] : arguments;
return new JsonSql(function ()
{
var index = 0;
return new IEnumerator(
Functions.Blank,
function ()
{
if (index >= args.length) index = 0;
return this.Yield(args[index++]);
},
Functions.Blank);
});
}
JsonSql.Empty = function ()
{
return new JsonSql(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return false; },
Functions.Blank);
});
}
function Trim(str)
{
return str.replace(/(^\s*)|(\s*$)/g, "");
}
JsonSql.Sql = function (obj)
{
//JsonSql.Sql("select {day:$[0],close:$[2]} from gp where $.close == JsonSql.From(gp).Min('$[2]')").ToJSON()
var from=obj.substr(obj.indexOf("from")+4,obj.indexOf("where")-obj.indexOf("from")-4);
if(!from){
from=obj.substr(obj.indexOf("from")+4);
}
var select=obj.substr(obj.indexOf("select")+6,obj.indexOf("from")-obj.indexOf("select")-6);
var where=obj.substr(obj.indexOf("where")+5);
if(obj.indexOf("where") == -1){
where="";
}
from=Trim(from);
if(from){
from=eval(from);
}
select=Trim(select);
if(select=="*"){
select="";
}
where=Trim(where);
var sql=JsonSql.From(from).Select(select).Where(where);
return sql;
}
JsonSql.From = function (obj)
{
if (obj == null)
{
return JsonSql.Empty();
}
if (obj instanceof JsonSql)
{
return obj;
}
if (typeof obj == Types.Number || typeof obj == Types.Boolean)
{
return JsonSql.Repeat(obj, 1);
}
if (typeof obj == Types.String)
{
return new JsonSql(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 ArrayJsonSql(obj);
}
// JScript's IJsonSql
if (!(obj instanceof Object) && Utils.IsIJsonSql(obj))
{
return new JsonSql(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 JsonSql(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);
});
},
JsonSql.Return = function (element)
{
return JsonSql.Repeat(element, 1);
}
// Overload:function(input, pattern)
// Overload:function(input, pattern, flags)
JsonSql.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 JsonSql(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)
JsonSql.Range = function (start, count, step)
{
if (step == null) step = 1;
return JsonSql.ToInfinity(start, step).Take(count);
}
// Overload:function(start, count)
// Overload:function(start, count, step)
JsonSql.RangeDown = function (start, count, step)
{
if (step == null) step = 1;
return JsonSql.ToNegativeInfinity(start, step).Take(count);
}
// Overload:function(start, to)
// Overload:function(start, to, step)
JsonSql.RangeTo = function (start, to, step)
{
if (step == null) step = 1;
return (start < to)
? JsonSql.ToInfinity(start, step).TakeWhile(function (i) { return i <= to; })
: JsonSql.ToNegativeInfinity(start, step).TakeWhile(function (i) { return i >= to; })
}
// Overload:function(obj)
// Overload:function(obj, num)
JsonSql.Repeat = function (obj, num)
{
if (num != null) return JsonSql.Repeat(obj).Take(num);
return new JsonSql(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(obj); },
Functions.Blank);
});
}
JsonSql.RepeatWithFinalize = function (initializer, finalizer)
{
initializer = Utils.CreateLambda(initializer);
finalizer = Utils.CreateLambda(finalizer);
return new JsonSql(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)
JsonSql.Generate = function (func, count)
{
if (count != null) return JsonSql.Generate(func).Take(count);
func = Utils.CreateLambda(func);
return new JsonSql(function ()
{
return new IEnumerator(
Functions.Blank,
function () { return this.Yield(func()); },
Functions.Blank);
});
}
// Overload:function()
// Overload:function(start)
// Overload:function(start, step)
JsonSql.ToInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1;
return new JsonSql(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)
JsonSql.ToNegativeInfinity = function (start, step)
{
if (start == null) start = 0;
if (step == null) step = 1;
return new JsonSql(function ()
{
var value;
return new IEnumerator(
function () { value = start + step },
function () { return this.Yield(value -= step); },
Functions.Blank);
});
}
JsonSql.Unfold = function (seed, func)
{
func = Utils.CreateLambda(func);
return new JsonSql(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
JsonSql.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 JsonSql(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 = JsonSql.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 JsonSql(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 = JsonSql.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 { JsonSql.From(enumeratorStack).ForEach(function (s) { s.Dispose(); }) }
});
});
},
Flatten: function ()
{
var source = this;
return new JsonSql(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 = JsonSql.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 JsonSql(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 JsonSql(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 JsonSql(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 JsonSql(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 = JsonSql.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 JsonSql(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 JsonSql(function ()
{
var firstEnumerator;
var secondEnumerator;
var index = 0;
return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = JsonSql.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 JsonSql(function ()
{
var outerEnumerator;
var lookup;
var innerElements = null;
var innerCount = 0;
return new IEnumerator(
function ()
{
outerEnumerator = source.GetEnumerator();
lookup = JsonSql.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 JsonSql(function ()
{
var enumerator = source.GetEnumerator();
var lookup = null;
return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
lookup = JsonSql.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 JsonSql(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 = JsonSql.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 JsonSql(function ()
{
var firstEnumerator;
var secondEnumerator;
var count = 0;
var isEnumerated = false;
return new IEnumerator(
function ()
{
firstEnumerator = source.GetEnumerator();
secondEnumerator = JsonSql.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 = JsonSql.Return(value);
return this.SelectMany(function (elem)
{
return JsonSql.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 JsonSql(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(JsonSql.Empty(), compareSelector);
},
// Overload:function(second)
// Overload:function(second, compareSelector)
Except: function (second, compareSelector)
{
compareSelector = Utils.CreateLambda(compareSelector);
var source = this;
return new JsonSql(function ()
{
var enumerator;
var keys;
return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
JsonSql.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 JsonSql(function ()
{
var enumerator;
var keys;
var outs;
return new IEnumerator(
function ()
{
enumerator = source.GetEnumerator();
keys = new Dictionary(compareSelector);
JsonSql.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 = JsonSql.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 JsonSql(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 = JsonSql.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 OrderedJsonSql(this, keySelector, false);
},
OrderByDescending: function (keySelector)
{
return new OrderedJsonSql(this, keySelector, true);
},
Reverse: function ()
{
var source = this;
return new JsonSql(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 JsonSql(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 JsonSql(function ()
{
var enumerator;
return new IEnumerator(
function ()
{
enumerator = source.ToLookup(keySelector, elementSelector, compareSelector)
.ToJsonSql()
.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 JsonSql(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, JsonSql.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 JsonSql(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) {
if(isNaN(a)==false && isNaN(b)==false){
a=parseFloat(a);
b=parseFloat(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)
{
if(isNaN(a)==false && isNaN(b)==false){
a=parseFloat(a);
b=parseFloat(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 JsonSql(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 JsonSql(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 JsonSql(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 JsonSql(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 JsonSql(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 JsonSql.Empty();
var source = this;
return new JsonSql(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 = JsonSql.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 JsonSql(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 JsonSql(function ()
{
var enumerator;
return new IEnumerator(
function ()
{
enumerator = JsonSql.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 JsonSql(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 JsonSql(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 JsonSql(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 JsonSql(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;
},
IsIJsonSql: 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 OrderedJsonSql = function (source, keySelector, descending, parent)
{
this.source = source;
this.keySelector = Utils.CreateLambda(keySelector);
this.descending = descending;
this.parent = parent;
}
OrderedJsonSql.prototype = new JsonSql();
OrderedJsonSql.prototype.CreateOrderedJsonSql = function (keySelector, descending)
{
return new OrderedJsonSql(this.source, keySelector, descending, this);
}
OrderedJsonSql.prototype.ThenBy = function (keySelector)
{
return this.CreateOrderedJsonSql(keySelector, false);
}
OrderedJsonSql.prototype.ThenByDescending = function (keySelector)
{
return this.CreateOrderedJsonSql(keySelector, true);
}
OrderedJsonSql.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 (orderedJsonSql, currentContext)
{
var context = new SortContext(orderedJsonSql.keySelector, orderedJsonSql.descending, currentContext);
if (orderedJsonSql.parent != null) return SortContext.Create(orderedJsonSql.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 ArrayJsonSql = function (source)
{
this.source = source;
}
ArrayJsonSql.prototype = new JsonSql();
ArrayJsonSql.prototype.Any = function (predicate)
{
return (predicate == null)
? (this.source.length > 0)
: JsonSql.prototype.Any.apply(this, arguments);
}
ArrayJsonSql.prototype.Count = function (predicate)
{
return (predicate == null)
? this.source.length
: JsonSql.prototype.Count.apply(this, arguments);
}
ArrayJsonSql.prototype.ElementAt = function (index)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: JsonSql.prototype.ElementAt.apply(this, arguments);
}
ArrayJsonSql.prototype.ElementAtOrDefault = function (index, defaultValue)
{
return (0 <= index && index < this.source.length)
? this.source[index]
: defaultValue;
}
ArrayJsonSql.prototype.First = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[0]
: JsonSql.prototype.First.apply(this, arguments);
}
ArrayJsonSql.prototype.FirstOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return JsonSql.prototype.FirstOrDefault.apply(this, arguments);
}
return this.source.length > 0 ? this.source[0] : defaultValue;
}
ArrayJsonSql.prototype.Last = function (predicate)
{
return (predicate == null && this.source.length > 0)
? this.source[this.source.length - 1]
: JsonSql.prototype.Last.apply(this, arguments);
}
ArrayJsonSql.prototype.LastOrDefault = function (defaultValue, predicate)
{
if (predicate != null)
{
return JsonSql.prototype.LastOrDefault.apply(this, arguments);
}
return this.source.length > 0 ? this.source[this.source.length - 1] : defaultValue;
}
ArrayJsonSql.prototype.Skip = function (count)
{
var source = this.source;
return new JsonSql(function ()
{
var index;
return new IEnumerator(
function () { index = (count < 0) ? 0 : count },
function ()
{
return (index < source.length)
? this.Yield(source[index++])
: false;
},
Functions.Blank);
});
};
ArrayJsonSql.prototype.TakeExceptLast = function (count)
{
if (count == null) count = 1;
return this.Take(this.source.length - count);
}
ArrayJsonSql.prototype.TakeFromLast = function (count)
{
return this.Skip(this.source.length - count);
}
ArrayJsonSql.prototype.Reverse = function ()
{
var source = this.source;
return new JsonSql(function ()
{
var index;
return new IEnumerator(
function ()
{
index = source.length;
},
function ()
{
return (index > 0)
? this.Yield(source[--index])
: false;
},
Functions.Blank)
});
}
ArrayJsonSql.prototype.SequenceEqual = function (second, compareSelector)
{
if ((second instanceof ArrayJsonSql || second instanceof Array)
&& compareSelector == null
&& JsonSql.From(second).Count() != this.Count())
{
return false;
}
return JsonSql.prototype.SequenceEqual.apply(this, arguments);
}
ArrayJsonSql.prototype.ToString = function (separator, selector)
{
if (selector != null || !(this.source instanceof Array))
{
return JsonSql.prototype.ToString.apply(this, arguments);
}
if (separator == null) separator = "";
return this.source.join(separator);
}
ArrayJsonSql.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;
},
ToJsonSql: function ()
{
var self = this;
return new JsonSql(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 JsonSql.From(dictionary.Get(key));
}
this.Contains = function (key)
{
return dictionary.Contains(key);
}
this.ToJsonSql = function ()
{
return dictionary.ToJsonSql().Select(function (kvp)
{
return new Grouping(kvp.Key, kvp.Value);
});
}
}
var Grouping = function (key, elements)
{
this.Key = function ()
{
return key;
}
ArrayJsonSql.call(this, elements);
}
Grouping.prototype = new ArrayJsonSql();
// out to global
return JsonSql;
})()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/leoasc/JsonSql.git
[email protected]:leoasc/JsonSql.git
leoasc
JsonSql
JsonSql.js
master

搜索帮助