lambda.js 的由来
作为一个当耐特程序员,对 lambda 一定不陌生。随着当耐特版本的更新迭代,C#也由委托==〉 匿名委托==〉lambda 表达式。由于 javascript 语言的约束,没有提供相应的 lambda 的机制,所以就有了 lambda.js,让广大 jser 也可以 (a,b)=>a.xx==”yyy”&&b>11 一把!
Query Operator
而 lambda 最常用的地方就是 Query Operator。
比如下面一些 C# code:
1 2 |
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddNumbers = numbers.Count(n => n % 2 == 1); |
对应的 javascript code(不使用 lambda.js)
1 2 |
var numbers = [ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ]; var oddNumbers = _(numbers).count(function (item) { return item % 2 === 1 }); |
使用 lambda.js 之后
1 2 |
var numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]; var oddNumbers = _(numbers).count(_("a=>a%2===1")); |
lambda.js 当然提供了 underscore.js 和 JSLINQ 都包含的功能!当然 lambda.js 编程风格更接近 jquery style(连缀,大部分方法返回 lambda 对象)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
var numbers = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0]; var oddNumbers = _(numbers).count(_("a=>a%2===1")); console.log(oddNumbers===5) //数组 _(["aa", "bb", "cc"]).each(function (index, item) { if (index === 0) console.log("arrry each:"+("aa" === item)); if (index === 1) console.log("arrry each:" +( "bb" === item)); if (index === 2) console.log("arrry each:" +( "cc" === item)); }) //支持对象 _({ x: 100, y: 200, name: "zhanglei" }).each(function (key, value) { if (key == "x") console.log("obj each:" +( value === 100)); if (key == "y") console.log("obj each:"+(value === 200)); if (key == "name") console.log("obj each:"+(value === "zhanglei")); }) ////支持map var aa = _([1, 2, 3]).map(function (item) { return item * 3; }).items console.log("map:"+(aa[0] === 3)) console.log("map:"+(aa[1] === 6)) console.log("map:"+(aa[2] === 9)) //支持对象的数组 var stooges1 = [{ name: 'zhanglei', age: 17 }, { name: 'curly', age: 25 }, { name: 'moe', age: 21 }, { name: 'larry', age: 23 }]; var youngest = _(stooges1).map(function (item) { return item.name + ' is ' + item.age; }).items console.log(youngest) //支持查找 var even = _([7, 2, 3, 4, 5, 6, 7, 8, 9]).find(function (item) { return item % 2 == 0; }).items; console.log(even) |
这些都不是关键,关键是可以 lambda 化,比如这个查询:
1 2 3 4 5 6 7 8 9 10 |
var stooges3 = [{ name: 'zhanglei', age: 17 }, { name: 'curly', age: 25 }, { name: 'moe', age: 21 }, { name: 'larry', age: 23 }]; var over18 = _(stooges3) .find(function (item, index) { return item.age >= 18 && index>0}) .sortBy(function (item) { return item.age }) .first(function (item) { return item.age > 21 }) .map(function (stooge) { return stooge.name + ' is ' + stooge.age; }) .items ; console.log(over18); |
lambda 化之后:
1 2 3 4 5 6 7 8 9 |
var stooges3 = [{ name: 'zhanglei', age: 17 }, { name: 'curly', age: 25 }, { name: 'moe', age: 21 }, { name: 'larry', age: 23 }]; var over18 = _(stooges3) .find(_("(a,b)=> a.age >= 18 && b > 0 ")) .sortBy(_("b=>b.age")) .first(_("item=>item.age>21")) .map(_("i=>i.name + ' is ' + i.age;")) .items ; |
lambda.js 预览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
(function (window) { var lambda = function (items) { if (lambda.type(items) === "string") return lambda._compile(items); return new lambda.prototype.init(items); }, _lambda = window.lambda, __ = window._; lambda.prototype.init = function (items) { this.items = items; return this; } lambda.prototype.each = function (fn) { var name, i = 0, length = this.items.length, isObj = length === undefined || lambda.type(this.items) === "function"; var its = this.items; if (isObj) { for (name in its) { fn.call(its[name], name, its[name]); } } else { for (; i < its.length;) { fn.call(its[i], i, its[i++]); } } } lambda.prototype.count= function(fn) { if (fn == null) return this.items.length; else return this.find(fn).items.length; } lambda.prototype.map = function (fn) { var result = []; this.each(function (index,item) { result[index]=fn(item); }) return lambda(result); } lambda.prototype.first = function (fn) { if (fn != null) { return this.find(fn).first(); } else { // If no clause was specified, then return the First element in the Array if (this.items.length > 0) return lambda([this.items[0]]); else return null; } } lambda.prototype.find = function (fn) { var newArr=[], self = this, i = 0; this.each(function (index, item) { if (fn(item,index)) newArr[i++] = item; }) return lambda(newArr); } lambda.prototype.sortBy = function (clause) { var tempArray = []; for (var i = 0; i < this.items.length; i++) { tempArray[tempArray.length] = this.items[i]; } return lambda( tempArray.sort(function (a, b) { var x = clause(a); var y = clause(b); return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }) ); } lambda.type = function (obj) { return obj == null ? String(obj) : { "[object Array]": "array", "[object Boolean]": "boolean", "[object Date]": "date", "[object Function]": "function", "[object Number]": "number", "[object Object]": "object", "[object RegExp]": "regexp", "[object String]": "string" }[Object.prototype.toString.call(obj)] || "object"; } lambda._compile = function (condition) { var conditionStr = condition.split("=>"); if (conditionStr[0].indexOf("(") === -1) { return function (item) { return eval(conditionStr[1].replace(new RegExp("\\b" + conditionStr[0] + "(?![A-Za-z0-9_])", "g"), "item")); } } else { var tempStr = conditionStr[0].replace(/\(/g, "").replace(/\)/g, "").split(","); var tempItem = lambda.trim(tempStr[0]); var tempIndex = lambda.trim(tempStr[1]); return function (item,index) { return eval(conditionStr[1].replace(new RegExp("\\b" + tempItem + "(?![A-Za-z0-9_])", "g"), "item").replace(new RegExp("\\b" + tempIndex + "(?![A-Za-z0-9_])", "g"), "index")); } } } var trimLeft = /^\s+/, trimRight = /\s+$/, rnotwhite = /\S/, trim = String.prototype.trim; // IE doesn't match non-breaking spaces with \s if (rnotwhite.test("\xA0")) { trimLeft = /^[\s\xA0]+/; trimRight = /[\s\xA0]+$/; } lambda.trim = trim ? function (text) { return text == null ? "" : trim.call(text); } : // Otherwise use our own trimming functionality function (text) { return text == null ? "" : text.toString().replace(trimLeft, "").replace(trimRight, ""); }; lambda.prototype.init.prototype = lambda.prototype; lambda.noConflict = function (deep) { if (window._ === lambda) { window._ = __; } if (deep && window.lambda === lambda) { window.lambda = _lambda; } return lambda; } var root = this; if (typeof exports !== 'undefined') { if (typeof module !== 'undefined' && module.exports) { exports = module.exports = lambda = _; } exports.lambda = exports._ = lambda; } else { root.lambda = root._ = lambda; } }(window)) |
完整 demo 下载
欢迎任何问题或者建议。