• lodash用法系列(5),链式


    Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能。

    官网:https://lodash.com/
    引用:<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
    安装:npm install lodash

    首先通过npm安装lodash:
    npm i --save lodash

    在js文件中引用lodash:
    var _ = require('lodash');

    本系列包括:

    lodash用法系列(1),数组集合操作
    lodash用法系列(2),处理对象 
    lodash用法系列(3),使用函数 
    lodash用法系列(4),使用Map/Reduce转换  
    lodash用法系列(5),链式 
    lodash用法系列(6),函数种种 

    ■ 对字符串数组链式

    var result = _(['a','b','c'])
        .at([0,1])
        .value();
    
    //[ 'a', 'b' ]
    console.log(result);

    ■ 对对象链式

    _({a: 'b', c: 'd'})
    .contains('b');

    ■ 对字符串链式

    _('abcd')
    .contains('b');

    ■ 使用chain实现链式

    _.chain([3,2,1])
    .sort()
    .first()
    .isNumber()
    .value();

    ■ 多个过滤的链式

    var collection = [
        { name: 'Ellen', age: 20, enabled: true },
        { name: 'Heidi', age: 24, enabled: false },
        { name: 'Roy', age: 21, enabled: true },
        { name: 'Garry', age: 23, enabled: false }
    ];
    _(collection)
        .filter('enabled')
        .filter(function(item) {
            return item.age >= 21;
        })
        .value();
    // → [ { name: "Roy", age: 21, enabled: true } ]

    ■ filter结合where的链式

    var collection = [
        { name: 'Janice', age: 38, gender: 'f' },
        { name: 'Joey', age: 20, gender: 'm' },
        { name: 'Lauren', gender: 'f' },
        { name: 'Drew', gender: 'm' }
    ];
    _(collection)
        .where({ gender: 'f' })
        .filter(_.flow(_.property('age'), _.isFinite))
        .value();
    // → [ { name: "Janice", age: 38, gender: "f" } ]

    ■ sortBy结合dropWhile链式

    var collection = [
        { first: 'Dewey', last: 'Mills' },
        { first: 'Charlene', last: 'Larson' },
        { first: 'Myra', last: 'Gray' },
        { first: 'Tasha', last: 'Malone' }
    ];
    _(collection)
        .sortBy('first')
        .dropWhile(function(item) {
            return _.first(item.first) < 'F';
        })
        .value();
    //
    // [
    // { first: "Myra", last: "Gray" },
    // { first: "Tasha", last: "Malone" }
    // ]

    ■ trim字符串

    var name = ' Donnie Woods ',
        emptyString = _.partial(_.isEqual, ' ');
    _(name)
        .toArray()
        .dropWhile(emptyString)
        .dropRightWhile(emptyString)
        .join('');
    // → "Donnie Woods"


    ■ sortBy结合takeWhile链式,获取满足条件的对象集合元素

    var collection = [
        { name: 'Jeannie', grade: 'B+' },
        { name: 'Jeffrey', grade: 'C' },
        { name: 'Carrie', grade: 'A-' },
        { name: 'James', grade: 'A' }
    ];
    _(collection)
        .sortBy('grade')
        .takeWhile(function(item) {
            return _.first(item.grade) === 'A';
        })
        .value();
    
    //
    // [
    // { name: "James", grade: "A" },
    // { name: "Carrie", grade: "A-" }
    // ]

    ■ reject链式

    var obj = {
        first:'a',
        last:'b',
        age:25,
        enabled:true
    };
    
    var tempResult = _(obj)
        .reject(_.isBoolean)
        .reject(_.isString)
        .value();
    
    //[ 25 ]
    console.log(tempResult);

    reject还可以接受回调函数。

    function User(name, disabled){
        this.name = name;
        this.disabled = disabled;
    }
    
    User.prototype.enabled = function(){
        return !this.disabled;
    }
    
    var collection = [
            new User('Phil', true),
            new User('Wilson', false),
            new User('Kathey', true),
            new User('Nina', false)
        ],
    
        //作为下面reject的回调函数
        enabled = _.flow(_.identity,
            _.partialRight(_.result, 'enabled'));//由于是作为reject的回调函数,这里的enabled是User的原型方法enabled
    
    var result = _(collection)
        .reject('disabled')
        .value();
    
    //[ User { name: 'Wilson', disabled: false },
    //    User { name: 'Nina', disabled: false } ]
    console.log(result);
    
    var result2 =_(collection)
        .reject(_.negate(enabled))
        .value();
    
    //[ User { name: 'Wilson', disabled: false },
    //    User { name: 'Nina', disabled: false } ]
    console.log(result2);

    ■ 关于negate方法

    function isEven(num) {
        return num % 2 == 0;
    }
    
    var result = _.filter([1, 2, 3, 4, 5, 6], isEven);
    var negateResult = _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
    
    //[ 2, 4, 6 ]
    console.log(result);
    
    [ 1, 3, 5 ]
    console.log(negateResult);

    ■ initial只接受除了集合中最后一个元素之外的所有元素

    对于一个字符串,先用分步来做:

    var string = 'abc
    ';
    
    var result1 = _(string)
        .slice()
        .value();
    
    //[ 'a', 'b', 'c', '
    ' ]
    console.log(result1);
    
    var result2 = _(result1)
        .initial()
        .value();
    
    //[ 'a', 'b', 'c' ]
    console.log(result2)
    
    var result3=_(result2)
        .join('');
    
    //abc
    console.log(result3);

    然后用链式可以这样做:

    var oneResult = _(string)
        .slice()
        .initial()
        .join('');
    
    //abc
    console.log(oneResult);

    ■ rest只接受除了集合中第一个元素之外的所有元素

    var collection = [
        { name: 'init', task: _.noop },
        { name: 'sort', task: _.random },
        { name: 'search', task: _.random }
    ];
    
    var result = _(collection)
        .rest()
        .invoke('task')
        .value();
    
    //[ 1, 0 ] 有时候是 [ 0, 0 ],不一定
    console.log(result);

    ■ 判断字符串是否含有某些字符串

    var string = 'abc123';
    
    var result =_(string)
        .filter(_.isString)
        .contains('c');
    
    console.log(result);//true

    ■ 判断数组中是否包含某个元素

    var array = [ 'a', 'b', 'c', 1, 2, 3 ];
    
    var result = _(array)
        .filter(_.isString)
        .contains('c');
    
    console.log(result);//true

    ■ 所有集合元素都符合某种条件

    var collection = [
        1414728000000,
        1383192000000,
        1351656000000,
        1320033600000
    ];
    _(collection)
        .map(function(item) {
            return new Date(item);
        })
        .every(function(item) {
            return item.getMonth() === 9 && item.getDate() === 31;
        });
    // → true


    ■ 只要集合元素某些符合某种条件

    var collection = [
        { name: 'Danielle', age: 34, skill: 'Backbone' },
        { name: 'Sammy', age: 19, skill: 'Ember' },
        { name: 'Donna', age: 41, skill: 'Angular' },
        { name: 'George', age: 17, skill: 'Marionette' }
    ];
    
    
    var result=_(collection)
        .reject({ skill: 'Ember' })
        .reject({ skill: 'Angular' })
        .some(function(item) {
            return item.age >= 25;
        });
    
    console.log(result);//true

    ■ size运用到对象上数的是键值对的数量

    var object = { first: 'Charlotte', last: 'Hall' };
    
    var result1 = _(object)
        .size();
    console.log(result1);//2
    
    var result2 = _(object)
        .omit('first')
        .size();
    
    console.log(result2);//1

    ■ size运用到数组上数的是元素的数量

    var array = _.range(10);
    
    var result =_(array)
        .drop(5)
        .size();
    
    console.log(result);//5

    ■ countBy对对象某个字段的值进行分组并计数

    如果分步走,就是:

    var collection = [
        { name: 'Pamela', gender: 'f' },
        { name: 'Vanessa', gender: 'f' },
        { name: 'Gina', gender: 'f' },
        { name: 'Dennis', gender: 'm' }
    ];
    
    //countBy对对象某个字段的值进行分组并计数
    var r1 =_(collection)
        .countBy('gender')
        .value();
    console.log(r1);//{ f: 3, m: 1 }
    
    //paris把对象的每一个键值作为数组元素,再把这个数组放到更大的数组
    var r2=_(r1)
        .pairs()
        .value();
    console.log(r2);//[ [ 'f', 3 ], [ 'm', 1 ] ]
    
    //排序
    var r3=_(r2)
        .sortBy(1)
        .value();
    console.log(r3);//[ [ 'm', 1 ], [ 'f', 3 ] ]
    
    //反转
    var r4=_(r3)
        .reverse()
        .value();
    console.log(r4);//[ [ 'f', 3 ], [ 'm', 1 ] ]
    
    //pluck获取想要的集合元素
    var r5=_(r4)
        .pluck(0)
        .value();
    console.log(r5);//[ 'f', 'm' ]

    如果是链式,就是:

    _(collection)
        .countBy('gender')
        .pairs()
        .sortBy(1)
        .reverse()
        .pluck(0)
        .value();

    ■ 对象的集合,对象元素中有数组字段,根据数组元素的某些条件自定义求和算法

    var collection = [
        { name: 'Chad', skills: [ 'backbone', 'lodash' ] },
        { name: 'Simon', skills: [ 'html', 'css', 'less' ] },
        { name: 'Katie', skills: [ 'grunt', 'underscore' ] },
        { name: 'Jennifer', skills: [ 'css', 'grunt', 'less' ] }
    ];
    
    var result = _(collection)
        .pluck('skills')
        .reduce(function(result, item){
            return _.size(item) > 2 &&
                _.contains(item, 'grunt') &&
                    result + 1;
        },0);
    
    console.log(result);//1


    以上,通过pluck对象元素只留下了skills,是一个数组类型。通过reduce方法在满足多个条件下求和。size统计对象字段数组的元素个数,contains判断对象字段数组中是否包含某个元素。

    ■ 对象数组,为对象元素加上新的字段并分组

    var collection = [
        { name: 'Rudolph', age: 24 },
        { name: 'Charles', age: 43 },
        { name: 'Rodney', age: 37 },
        { name: 'Marie', age: 28 }
    ];
    
    var result = _(collection)
        .map(function(item){
            var experience='seasoned veteran';
            if(item.age<30){
                experience='noob';
            } else if(item.age<40){
                experience='geek cred';
            }
    
            return _.extend({experience: experience},item);
        })
        .groupBy('experience')
        .map(function(item,key){
            return key + ' ('+ _.pluck(item,'name').join(', ')+')';
        })
        .value();
    
    //[ 'noob (Rudolph, Marie)',
    //    'seasoned veteran (Charles)',
    //    'geek cred (Rodney)' ]
    console.log(result);

    ■ 两个数组的并集

    var collection=_.sample(_.range(1,101),10);
    
    
    var result=_(collection)
        .union([25,50])
        .sortBy()
        .value();
    
    //[ 5, 18, 25, 40, 50, 62, 64, 72, 77, 78, 82, 87 ]
    console.log(result);

    ■ 对象集合,去掉对象元素字段重复值

    function name(item){
        return item.first + ' '+item.last;
    }
    
    var collection = [
        { first: 'Renee', last: 'Morris' },
        { first: 'Casey', last: 'Wise' },
        { first: 'Virginia', last: 'Grant' },
        { first: 'Toni', last: 'Morris' }
    ];
    
    var result1 = _(collection)
        .uniq('last') //去掉last字段重复的值
        .sortBy('last')
        .value();
    console.log(result1);

    ■ 对象数组,where结合pluck链式

    var collection = [
        { gender: 'f', dob: new Date(1984, 3, 8) },
        { gender: 'm', dob: new Date(1983, 7, 16) },
        { gender: 'f', dob: new Date(1987, 2, 4) },
        { gender: 'm', dob: new Date(1988, 5, 2) }
    ];
    
    
    var result =_(collection)
        .where({gender: 'm'})
        .pluck('dob')
        .map(function(item){
            return item.toLocaleString();
        })
        .value();
    
    //[ '1983-08-16 00:00:00', '1988-06-02 01:00:00' ]
    console.log(result);

    ■ without排除数组元素

    var collection= _.range(1,11);
    
    var result = _(collection)
        .without(5, _.first(collection), _.last(collection))
        .reverse()
        .value();
    
    //[ 9, 8, 7, 6, 4, 3, 2 ]
    console.log(result);

    ■ 对象数组,找出某个字段满足最小值的对象元素

    var collection = [
        { name: 'Daisy', wins: 10 },
        { name: 'Norman', wins: 12 },
        { name: 'Kim', wins: 8 },
        { name: 'Colin', wins: 4 }
    ];
    
    var result=_(collection)
        .reject(function(item){
            return item.wins<5;
        })
        .min('wins');
    
    //{ name: 'Kim', wins: 8 }
    console.log(result);

    ■ 对象数组,计算对象元素的字段的最大值,找出其所对应的对象元素

    var collection = [
        { name: 'Kerry', balance: 500, credit: 344 },
        { name: 'Franklin', balance: 0, credit: 554 },
        { name: 'Lillie', balance: 1098, credit: 50 },
        { name: 'Clyde', balance: 473, credit: -900 }
    ];
    
    var result=_(collection)
        .filter('balance')
        .filter('credit')
        .max(function(item){
            return item.balance +item.credit;
        })
    
    //{ name: 'Lillie', balance: 1098, credit: 50 }
    console.log(result);

    ■ 对象集合,找出附后某个字段值条件的对象元素在数组中的位置

    function rank(coll, name){
        return _(coll)
            .sortBy('score')
            .reverse()
            .pluck('name')
            .indexOf(name) + 1;
    }
    
    var collection = [
        { name: 'Ruby', score: 43 },
        { name: 'Robert', score: 59 },
        { name: 'Lindsey', score: 38 },
        { name: 'Marty', score: 55 }
    ];
    
    var result = rank(collection, 'Ruby');
    
    console.log(result);//3

    ■ 获取两个数组的差集

    var collection = _.range(1, 51),//1-50的数
        odds = _.filter(_.range(1, 101), function(item) {
            return item % 2;
        });//1-100的偶数
        
    _(collection)
        .difference(odds)
        .takeRight(10)
        .reverse()
        .value();    

    分开写就是:

    var collection = _.range(1, 51),//1-50的数
        odds = _.filter(_.range(1, 101), function(item) {
            return item % 2;
        });//1-100的偶数
    
    var result1=_(collection)
        .difference(odds)//两个集合的差集
        .value();
    
    //[ 2,4,6,8,10,12,14,16,18,20,22,24,26,28, 30,32,34,36,38,40,42,44,46,48,50 ]
    console.log(result1);
    
    var result2=_(result1)
        .takeRight(10)
        .value();
    
    //[ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50 ]
    console.log(result2);
    
    var result3 = _(result2)
        .reverse()
        .value();
    
    //[ 50, 48, 46, 44, 42, 40, 38, 36, 34, 32 ]
    console.log(result3);

    ■ 获取两个数组的异或

    var collection = _.range(1, 26),
        evens = _.reject(_.range(1, 51), function(item) {
            return item % 2;
        });
        
    _(collection)
        .xor(evens)
        .reverse()
        .value();

    ■ 在链式中加入自己的回调函数,排除对象数组某个字段的最大和最小值

    var collection = [
            { name: 'Stuart', age: 41 },
            { name: 'Leah', age: 26 },
            { name: 'Priscilla', age: 37 },
            { name: 'Perry', age: 31 }
        ],
        min,
        max;
    
    var result = _(collection)
        .filter(function(item){
            return item.age >=30;
        })
        .tap(function(coll){
                min= _.min(coll,'age'),
                max= _.max(coll,'age')
        })
        .reject(function(item){
            return item.age === max.age;
        })
        .value();
    
    //[ { name: 'Priscilla', age: 37 }, { name: 'Perry', age: 31 } ]
    console.log(result);

    ■ 在链式中注入值

    var collection = _.range(1, _.random(11)),
        result;
    
    result=_(collection)
        .thru(function(coll){
            return _.size(coll)>5?coll:[];
        })
        .reverse()
        .value();
    
    var finalResult = _.isEmpty(result) ? 'No Results' : result.join(',');
    
    //有时 6,5,4,3,2,1
    //有时 No Results
    console.log(finalResult);

    ■ 过滤对象的键

    var object = {
        firstName: 'Jerald',
        lastName: 'Wolfe',
        age: 49
    };
    
    var result =_(object)
        .keys() //获取所有的键
        .filter(function(item){
            return (/name$/i).test(item);//不以name结尾的
        })
        .thru(function(items){//items表示过滤下来的键的集合
            return _.at(object, items);//从object中找出与这些键对相的键值
        })
        .value();
    
    //[ 'Jerald', 'Wolfe' ]
    console.log(result);

    ■ 过滤对象的值

    var object = {
        first: 'Connie',
        last: 'Vargas',
        dob: new Date(1984, 08, 11)
    };
    
    _(object)
        .values()
        .filter(_.isDate)
        .map(function(item) {
            return item.toLocaleString();
        })
        .value();
    // → [ "9/11/1984, 12:00:00 AM" ]

    ■ 对象数组,忽略对象元素某个字段

    var collection = [
        { first: 'Tracey', last: 'Doyle', age: 40 },
        { first: 'Toby', last: 'Wright', age: 49 },
        { first: 'Leonard', last: 'Hunt', age: 32 },
        { first: 'Brooke', last: 'Briggs', age: 32 }
    ];
    
    _(collection)
        .indexBy('last')
        .pick(function(value) {
            return value.age >= 35;
        })
        .transform(function(result, item, key) {
            result[key] = _.omit(item, 'last');
        })
        .value();
    //
    // {
    // Doyle: { first: "Tracey", age: 40 },
    // Wright: { first: "Toby", age: 49 }
    // }

    ■ 用来包裹一些列链式动作的函数可以看做是wrapper

    //coll集合
    //prop排序的属性
    //count要获取的数量
    function best(coll, prop, count){
        return _(coll)
            .sortBy(prop)
            .takeRight(count);
    }
    
    var collection = [
        { name: 'Mathew', score: 92 },
        { name: 'Michele', score: 89 },
        { name: 'Joe', score: 74 },
        { name: 'Laurie', score: 83 }
    ];
    
    var bestScore = best(collection, 'score',2);
    
    //[ { name: 'Michele', score: 89 },
    //    { name: 'Mathew', score: 92 } ]
    console.log(bestScore.value());
    
    best函数并没有真正执行,可以看做是一个wrapper。

    参考资料:lodash essentials

    未完待续~~

  • 相关阅读:
    (转载)C++ string中find() ,rfind() 等函数 用法总结及示例
    UVA 230 Borrowers (STL 行读入的处理 重载小于号)
    UVA 12100 打印队列(STL deque)
    uva 12096 The SetStack Computer(STL set的各种库函数 交集 并集 插入迭代器)
    uva 1592 Database (STL)
    HDU 1087 Super Jumping! Jumping! Jumping!
    hdu 1176 免费馅饼
    HDU 1003 Max Sum
    转战HDU
    hust 1227 Join Together
  • 原文地址:https://www.cnblogs.com/darrenji/p/5011488.html
Copyright © 2020-2023  润新知