• 码农干货系列【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下载

    欢迎任何问题或者建议。

  • 相关阅读:
    Linux 如何查看当前目录
    Docker快速入手实战笔记
    【ssh】ssh登录出现‘The authenticity of host ‘IP’ can't be established.’的问题
    【AFL(七)】afl-fuzz.c小改——输出文件夹暂存
    【steam】Steam背景美化——长展柜终极指南
    【AFL(六)】AFL源码中的那些头文件
    【AFL(五)】文件变异策略
    【Latex】详细的简易教程——写在论文开始之前
    【Latex】论文写作工具:VScode 2019 + latex workshop
    【AFL(四)】afl-cmin修改:文件夹相关操作鲁棒性
  • 原文地址:https://www.cnblogs.com/iamzhanglei/p/2836247.html
Copyright © 2020-2023  润新知