zoukankan      html  css  js  c++  java
  • 码农干货系列【5】lambda in js:lambda.js 1.0.0发布

    lambda.js的由来

    作为一个当耐特程序员,对lambda一定不陌生。随着当耐特版本的更新迭代,C#也由委托==〉匿名委托==〉lambda表达式。由于javascript语言的约束,没有提供相应的lambda的机制,所以就有了lambda.js,让广大jser也可以 (a,b)=>a.xx==”yyy”&&b>11 一把!

    Query Operator

    而lambda最常用的地方就是Query Operator。

    比如下面一些C# code:

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    int oddNumbers = numbers.Count(n => n % 2 == 1);

    对应的javascript code(不使用lambda.js)

    var numbers = [ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ];
    var oddNumbers = _(numbers).count(function (item) { return item % 2 === 1 });

    使用lambda.js之后

    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对象)。

            
            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化,比如这个查询:

        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化之后:

            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
            ;
    
    
    
            console.log(over18);

    lambda.js预览

    
    (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下载

    欢迎任何问题或者建议。

  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/iamzhanglei/p/2836247.html
Copyright © 2011-2022 走看看