LINQ

Linq for javascript

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/376052/690665/LINQ.js

  1. // ==UserScript==
  2. // @name LINQ
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description Linq for javascript
  6. // @author You
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. class Enumerable{
  11. constructor(iterable,isClosure=true){
  12. this.iterable=isClosure?iterable():iterable;
  13. this.extends=[];
  14. }
  15.  
  16. *[Symbol.iterator](){
  17. let cache=[];
  18. for(let x of this.iterable){
  19. cache.push(x);
  20. yield x;
  21. }
  22. for(let x of this.extends){
  23. cache.push(x);
  24. yield x;
  25. }
  26. this.iterable=cache;
  27. }
  28.  
  29. compare(a,b){
  30. a=a+"";
  31. b=b+"";
  32. let al=a.length;
  33. let bl=b.length;
  34. let n=al>bl?al:bl;
  35. for (let i=0;i<n;i++){
  36. if (i<al && i<bl){
  37. if (a.charCodeAt(i)>b.charCodeAt(i)){
  38. return 1;
  39. }
  40. else if (a.charCodeAt(i)<b.charCodeAt(i)){
  41. return -1;
  42. }
  43. }
  44. }
  45. if (al>bl){
  46. return 1;
  47. }
  48. else if (al<bl){
  49. return -1;
  50. }
  51. return 0;
  52. }
  53.  
  54. orderBy(selector){
  55. let sorted=this.toArray().sort((a,b)=>this.compare(selector(a),selector(b)));
  56. return new Enumerable(sorted,false);
  57. }
  58.  
  59. orderByDescending(selector){
  60. let sorted=this.toArray().sort((a,b)=>this.compare(selector(b),selector(a)));
  61. return new Enumerable(sorted,false);
  62. }
  63.  
  64. where(predicate){
  65. let a=this;
  66. return new Enumerable(function*(){
  67. for (let x of a){
  68. if (predicate(a)){
  69. yield x;
  70. }
  71. }
  72. });
  73. }
  74.  
  75. count(predicate){
  76. predicate=predicate || function(){return true;};
  77. let count=0;
  78. for(let x of this){
  79. if (predicate(x)){
  80. count+=1;
  81. }
  82. }
  83. return count;
  84. }
  85.  
  86. first(predicate){
  87. predicate=predicate || function(){return true;};
  88. for(let x of this){
  89. if (predicate(x)){
  90. return x;
  91. }
  92. }
  93. throw "Sequence least than 1";
  94. }
  95.  
  96. firstOrDefault(predicate){
  97. try {
  98. return this.first(predicate);
  99. }
  100. catch(e){
  101. return null;
  102. }
  103. }
  104.  
  105. elementAt(n){
  106. let id=0;
  107. for (let x of this){
  108. if (id==n){
  109. return x;
  110. }
  111. id++;
  112. }
  113. throw "Index of found";
  114. }
  115.  
  116. select(selector){
  117. let a=this;
  118. return new Enumerable(function*(){
  119. for(let x of a){
  120. yield selector(x);
  121. }
  122. });
  123. }
  124.  
  125. join(object,outerSelector,innerSelector,selector){
  126. let a=this;
  127. return new Enumerable(function*(){
  128. for(let x of a){
  129. for(let y of object){
  130. if (outerSelector(x)==innerSelector(y)){
  131. yield selector(x,y);
  132. }
  133. }
  134. }
  135. });
  136. }
  137.  
  138. groupBy(selector){
  139. let sorted=this.orderBy(selector);
  140. return new Enumerable(function(){
  141. let isSetInit=false;
  142. let key=null;
  143. let temp=null;
  144. let result=[];
  145. for(let x of sorted){
  146. if (!isSetInit){
  147. key=selector(x);
  148. temp=new Grouping(key,[x]);
  149. isSetInit=true;
  150. }
  151. else{
  152. if (selector(x)==key){
  153. temp.append(x);
  154. }
  155. else{
  156. key=selector(x);
  157. result.push(temp);
  158. temp=new Grouping(key,[x]);
  159. }
  160. }
  161. }
  162. result.push(temp);
  163. return result;
  164. });
  165. }
  166.  
  167. distinct(selector){
  168. return this.groupBy(selector).select(x=>x.first());
  169. }
  170.  
  171. toEnumerable(){
  172. return new Enumerable(this,false);
  173. }
  174.  
  175. toArray(){
  176. let result=[];
  177. for(let x of this){
  178. result.push(x);
  179. }
  180. return result;
  181. }
  182.  
  183. each(action){
  184. for (let x of this){
  185. action(x);
  186. }
  187. }
  188.  
  189. aggregate(func,initValue=null){
  190. let isSetInit=false;
  191. let accu=null;
  192. if (initValue!=null){
  193. accu=initValue;
  194. isSetInit=false;
  195. }
  196. for (let x of this){
  197. if (!isSetInit && accu==null){
  198. accu=x;
  199. continue;
  200. }
  201. accu=func(accu,x);
  202. }
  203. if (accu==null){
  204. throw "Sequence less than 1";
  205. }
  206. return accu;
  207. }
  208.  
  209. sum(selector){
  210. selector=selector || function(x){return x;};
  211. return this.select(selector).aggregate(function(accu,next){return accu+next;},0);
  212. }
  213.  
  214. max(selector){
  215. selector=selector || function(x){return x;};
  216. return this.select(selector).aggregate(function(accu,next){return accu>next?accu:next;});
  217. }
  218.  
  219. min(selector){
  220. selector=selector || function(x){return x;};
  221. return this.select(selector).aggregate(function(accu,next){return accu<next?accu:next;});
  222. }
  223.  
  224. unique(selector){
  225. return this.groupBy(selector).select(function(x){return x.first();});
  226. }
  227.  
  228. selectMany(collectionSelect=null,resultSelect=null){
  229. collectionSelect=collectionSelect || function(x){return x};
  230. resultSelect=resultSelect || function(x,y){return y;};
  231. let a=this;
  232. return new Enumerable(function*(){
  233. for(let x of a.select(collectionSelect)){
  234. for(let y of x){
  235. yield resultSelect(x,y);
  236. }
  237. }
  238. });
  239. }
  240.  
  241. static from(iterable){
  242. return new Enumerable(iterable,false);
  243. }
  244.  
  245. static range(from,to){
  246. return new Enumerable(function*(){
  247. for(let i=from;i<to;i++){
  248. yield i;
  249. }
  250. });
  251. }
  252.  
  253. static repeat(object,count){
  254. return new Enumerable(function*(){
  255. for(let i=0;i<count;i++){
  256. yield object;
  257. }
  258. });
  259. }
  260.  
  261. append(object){
  262. this.extends.push(object);
  263. }
  264. }
  265.  
  266. class Grouping extends Enumerable {
  267. constructor(key, iterable) {
  268. super(iterable,false);
  269. this.key = key;
  270. }
  271. }