1 //----------------------------------------------------------------------- 2 // Part of the LINQ to JavaScript (JSLINQ) v2.20 Project - http://jslinq.codeplex.com 3 // Copyright (C) 2012 Chris Pietschmann (http://pietschsoft.com). All rights reserved. 4 // This license can be found here: http://jslinq.codeplex.com/license 5 //----------------------------------------------------------------------- 6 (function () { 7 var JSLINQ = window.jslinq = window.JSLINQ = function (dataItems) { 8 return new JSLINQ.fn.init(dataItems); 9 }, 10 utils = { 11 processLambda: function (clause) { 12 // This piece of "handling" C#-style Lambda expression was borrowed from: 13 // linq.js - LINQ for JavaScript Library - http://lingjs.codeplex.com 14 // THANK!! 15 if (utils.isLambda(clause)) { 16 var expr = clause.match(/^[(\s]*([^()]*?)[)\s]*=>(.*)/); 17 return new Function(expr[1], "return (" + expr[2] + ")"); 18 } 19 return clause; 20 }, 21 isLambda: function (clause) { 22 return (clause.indexOf("=>") > -1); 23 }, 24 randomIndex: function (max, existing) { 25 var q, r, f = function () { return this == r; }; 26 if (!existing) { 27 return parseInt(Math.random() * max, 10); 28 } else { 29 q = JSLINQ(existing); 30 r = -1; 31 while (r < 0 || q.Where(f).Count() !== 0) { 32 r = utils.randomIndex(max); 33 } 34 return r; 35 } 36 } 37 }; 38 JSLINQ.fn = JSLINQ.prototype = { 39 init: function (dataItems) { 40 this.items = dataItems; 41 }, 42 43 // The current version of JSLINQ being used 44 jslinq: "2.20", 45 46 toArray: function () { return this.items; }, 47 where: function (clause) { 48 var newArray = [], len = this.items.length; 49 50 // The clause was passed in as a Method that return a Boolean 51 for (var i = 0; i < len; i++) { 52 if (clause.apply(this.items[i], [this.items[i], i])) { 53 newArray[newArray.length] = this.items[i]; 54 } 55 } 56 return JSLINQ(newArray); 57 }, 58 select: function (clause) { 59 var item, newArray = [], field = clause; 60 if (typeof (clause) !== "function") { 61 if (clause.indexOf(",") === -1) { 62 clause = function () { return this[field]; }; 63 } else { 64 clause = function () { 65 var i, fields = field.split(","), obj = {}; 66 for (i = 0; i < fields.length; i++) { 67 obj[fields[i]] = this[fields[i]]; 68 } 69 return obj; 70 }; 71 } 72 } 73 74 // The clause was passed in as a Method that returns a Value 75 for (var i = 0; i < this.items.length; i++) { 76 item = clause.apply(this.items[i], [this.items[i]]); 77 if (item) { 78 newArray[newArray.length] = item; 79 } 80 } 81 return JSLINQ(newArray); 82 }, 83 orderBy: function (clause) { 84 var tempArray = []; 85 for (var i = 0; i < this.items.length; i++) { 86 tempArray[tempArray.length] = this.items[i]; 87 } 88 89 if (typeof (clause) !== "function") { 90 var field = clause; 91 if (utils.isLambda(field)) { 92 clause = utils.processLambda(field); 93 } 94 else { 95 clause = function () { return this[field]; }; 96 } 97 } 98 99 return JSLINQ( 100 tempArray.sort(function (a, b) { 101 var x = clause.apply(a, [a]), y = clause.apply(b, [b]); 102 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 103 }) 104 ); 105 }, 106 orderByDescending: function (clause) { 107 var tempArray = [], field; 108 for (var i = 0; i < this.items.length; i++) { 109 tempArray[tempArray.length] = this.items[i]; 110 } 111 112 if (typeof (clause) !== "function") { 113 field = clause; 114 if (utils.isLambda(field)) { 115 clause = utils.processLambda(field); 116 } 117 else { 118 clause = function () { return this[field]; }; 119 } 120 } 121 122 return JSLINQ(tempArray.sort(function (a, b) { 123 var x = clause.apply(b, [b]), y = clause.apply(a, [a]); 124 return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 125 })); 126 }, 127 selectMany: function (clause) { 128 var r = []; 129 for (var i = 0; i < this.items.length; i++) { 130 r = r.concat(clause.apply(this.items[i], [this.items[i]])); 131 } 132 return JSLINQ(r); 133 }, 134 count: function (clause) { 135 if (clause === undefined) { 136 return this.items.length; 137 } else { 138 return this.Where(clause).items.length; 139 } 140 }, 141 distinct: function (clause) { 142 var item, dict = {}, retVal = []; 143 for (var i = 0; i < this.items.length; i++) { 144 item = clause.apply(this.items[i], [this.items[i]]); 145 // TODO - This doesn‘t correctly compare Objects. Need to fix this 146 if (dict[item] === undefined) { 147 dict[item] = true; 148 retVal.push(item); 149 } 150 } 151 dict = null; 152 return JSLINQ(retVal); 153 }, 154 any: function (clause) { 155 for (var i = 0; i < this.items.length; i++) { 156 if (clause.apply(this.items[i], [this.items[i], i])) { return true; } 157 } 158 return false; 159 }, 160 all: function (clause) { 161 for (var i = 0; i < this.items.length; i++) { 162 if (!clause(this.items[i], i)) { return false; } 163 } 164 return true; 165 }, 166 reverse: function () { 167 var retVal = []; 168 for (var i = this.items.length - 1; i > -1; i--) { 169 retVal[retVal.length] = this.items[i]; 170 } 171 return JSLINQ(retVal); 172 }, 173 first: function (clause) { 174 if (clause !== undefined) { 175 return this.Where(clause).First(); 176 } 177 else { 178 // If no clause was specified, then return the First element in the Array 179 if (this.items.length > 0) { 180 return this.items[0]; 181 } else { 182 return null; 183 } 184 } 185 }, 186 last: function (clause) { 187 if (clause !== undefined) { 188 return this.Where(clause).Last(); 189 } 190 else { 191 // If no clause was specified, then return the First element in the Array 192 if (this.items.length > 0) { 193 return this.items[this.items.length - 1]; 194 } else { 195 return null; 196 } 197 } 198 }, 199 elementAt: function (i) { 200 return this.items[i]; 201 }, 202 concat: function (array) { 203 var arr = array.items || array; 204 return JSLINQ(this.items.concat(arr)); 205 }, 206 intersect: function (secondArray, clause) { 207 var clauseMethod, sa = (secondArray.items || secondArray), result = []; 208 if (clause !== undefined) { 209 clauseMethod = clause; 210 } else { 211 clauseMethod = function (item, index, item2, index2) { return item === item2; }; 212 } 213 214 for (var a = 0; a < this.items.length; a++) { 215 for (var b = 0; b < sa.length; b++) { 216 if (clauseMethod(this.items[a], a, sa[b], b)) { 217 result[result.length] = this.items[a]; 218 } 219 } 220 } 221 return JSLINQ(result); 222 }, 223 defaultIfEmpty: function (defaultValue) { 224 if (this.items.length === 0) { 225 return defaultValue; 226 } 227 return this; 228 }, 229 elementAtOrDefault: function (i, defaultValue) { 230 if (i >= 0 && i < this.items.length) { 231 return this.items[i]; 232 } 233 return defaultValue; 234 }, 235 firstOrDefault: function (defaultValue) { 236 return this.First() || defaultValue; 237 }, 238 lastOrDefault: function (defaultValue) { 239 return this.Last() || defaultValue; 240 }, 241 take: function (count) { 242 return this.Where(function (item, index) { return index < count; }); 243 }, 244 skip: function (count) { 245 return this.Where(function (item, index) { return index >= count; }); 246 }, 247 each: function (clause) { 248 var len = this.items.length; 249 for (var i = 0; i < len; i++) { 250 clause.apply(this.items[i], [this.items[i], i]); 251 } 252 return this; 253 }, 254 random: function (count) { 255 var len = this.Count(), rnd = []; 256 if (!count) { count = 1; } 257 for (var i = 0; i < count; i++) { 258 rnd.push(utils.randomIndex(len - 1, rnd)); 259 } 260 rnd = JSLINQ(rnd); 261 return this.Where(function (item, index) { 262 return rnd.Where(function () { 263 return this == index; 264 }).Count() > 0; 265 }); 266 } 267 }; 268 269 (function (fn) { 270 fn.ToArray = fn.toArray; 271 fn.Where = fn.where; 272 fn.Select = fn.select; 273 fn.OrderBy = fn.orderBy; 274 fn.OrderByDescending = fn.orderByDescending; 275 fn.SelectMany = fn.selectMany; 276 fn.Count = fn.count; 277 fn.Distinct = fn.distinct; 278 fn.Any = fn.any; 279 fn.All = fn.all; 280 fn.Reverse = fn.reverse; 281 fn.First = fn.first; 282 fn.Last = fn.last; 283 fn.ElementAt = fn.elementAt; 284 fn.Concat = fn.concat; 285 fn.Intersect = fn.intersect; 286 fn.DefaultIfEmpty = fn.defaultIfEmpty; 287 fn.ElementAtOrDefault = fn.elementAtOrDefault; 288 fn.FirstOrDefault = fn.firstOrDefault; 289 fn.LastOrDefault = fn.lastOrDefault; 290 fn.Take = fn.take; 291 fn.Skip = fn.skip; 292 fn.Each = fn.each; 293 fn.Random = fn.random; 294 })(JSLINQ.fn); 295 296 JSLINQ.fn.init.prototype = JSLINQ.fn; 297 })();
具体分析下次有时间再写!
时间: 2024-11-06 13:46:32