darrenji

 

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 collection = [
    {name: \'\', age:45}
];

_.pluck(collection, \'age\');

 

也可以这样写:

_.map(collection, \'age\');

 

■ 对象的集合,留下想要的字段们

 

var collection = [
    {frist:\'\',last:\'\',age:23},
    ...
];

_.map(collection, function(item){
    return _.pick(item, [\'first\',\'last\']);
})

 


■ 对象的集合,排除不想要的字段们,不想要的字段作为参数传递

 

var collection = [
    {first:\'\',last:\'\',age:19},
    ...
];

_.map(collection, function(item){
    return _.omit(item, \'first\');
})

 

■ 对象的集合,排除不想要的字段们,通过函数

 

var collection = [
    {first:\'\',last:\'\',age:19},
    ...
];

//key 字段名称
//value 字段对应的值
function invalidAge(value, key){
    return key === \'age\' && value < 40;
}

_.map(collection, function(item){
    reutrn _.omit(item, invalidAge);
});

 

■ 对象的集合,给对象元素添加新的字段,根据现有字段计算而得

 

var collection = [
    { name: \'Valerie\', jqueryYears: 4, cssYears: 3 },
    { name: \'Alonzo\', jqueryYears: 1, cssYears: 5 },
    { name: \'Claire\', jqueryYears: 3, cssYears: 1 },
    { name: \'Duane\', jqueryYears: 2, cssYears: 0 }
];

var result = _.map(collection, function(item){
   return _.extend({
       experience: item.jqueryYears + item.cssYears,
       speciality: item.jqueryYears >= item.cssYears ? \'jQuery\' : \'CSS\'
   }, item);
});

//[ { experience: 7,speciality: \'jQuery\',name: \'Valerie\',jqueryYears: 4,cssYears: 3 },...]
console.log(result);

 

■ 使用map方法一个不易发现的错误

 

var app = {},
    collection = [
        { name: \'Cameron\', supervisor: false },
        { name: \'Lindsey\', supervisor: true },
        { name: \'Kenneth\', supervisor: false },
        { name: \'Caroline\', supervisor: true }
    ];

app.supervisor = _.find(collection, {supervisor:true});

//{ supervisor: { name: \'Lindsey\', supervisor: true } }
console.log(app);

_.map(collection, function(item){
   return _.extend(item, {supervisor: false});
});

//{ supervisor: { name: \'Lindsey\', supervisor: false } }
console.log(app);

 


以上,使用map对collection集合操作,重写supervisor字段的值,居然也把app对象的supervisor字段值也重写了。

■ map方法使用内置函数,计算每一个集合元素的大小

 

var collection=[
    [1,2],
    [1,2,3],
    {first:1, second:2},
    {first:1, second:2,third:3}
];

var result = _.map(collection, _.size);

//[ 2, 3, 2, 3 ]
console.log(result);

 

■ map方法使用内置函数,获取每个集合元素中的最小值

 

var source = _.range(1000),
    collection=[
        //sample从集合中获取一个或n个元素
        _.sample(source,50),
        _.sample(source,100),
        _.sample(source,150)
    ];

//[ 12, 44, 0 ]
console.log(_.map(collection, _.min));

 

■ map方法使用内置函数,针对集合元素依次调用多个方法

 

var collection = [
    [ \'Evan\', \'Veronica\', \'Dana\' ],
    [ \'Lila\', \'Ronald\', \'Dwayne\' ],
    [ \'Ivan\', \'Alfred\', \'Doug\' ],
    [ \'Penny\', \'Lynne\', \'Andy\' ]
];

var result = _.map(collection, _.flowRight(_.first, function(item){
    return _.sortBy(item);
}));

//[ \'Dana\', \'Dwayne\', \'Alfred\', \'Andy\' ]
console.log(result);

 


以上,flowRight方法会依次调用其参数方法,先给每个一个元素内的元素排序,然后取出元素中的元素中的第一个。

■ 对集合元素依次使用多个方法

 

var collection = [
    { name: \'Karl\', enabled: true },
    { name: \'Sophie\', enabled: true },
    { name: \'Jerald\', enabled: false },
    { name: \'Angie\', enabled: false }
];

var result = _.flowRight(
    _.partialRight(_.map, \'name\'),
    _.partialRight(_.filter, \'enabled\')
)(collection);


//[ \'Karl\', \'Sophie\' ]
console.log(result);

 


以上,对集合依次使用了filter和map方法。

■ 获取对象的所有键值

 

var object = {
    first: \'Ronald\',
    last: \'Walters\',
    employer: \'Packt\'
};

var result = _.map(_.sortBy(_.keys(object)), function(item){
    return object[item];
})

//[ \'Packt\', \'Ronald\', \'Walters\' ]
console.log(result);

 

以上,_.keys(object)获取对象的所有键,_.sortBy(_.keys(object))对所有键排序,然后根据键获取所有元素。

■ 创建唯一的自增编号

 

var result = _.uniqueId(\'user-\');
var result2 = _.uniqueId(\'user-\');
console.log(result);//user-1
console.log(result2);//user-2

 

以上,通过_.uniqueId(\'user-\');创建的编号是唯一、自增的。

■ 从两个具有相同键、相同键数量的对象中,取出对应的键、键值合并成一个新的对象,新的对象作为数组元素

 

ar users = {},
    prefereces = {};

_.each(_.range(100), function () {
    var id = _.uniqueId(\'user-\');
    users[id] = {type: \'user\'};
    prefereces[id] = {email: !!(_.random())}
});

//users:{ \'user-1\': { type: \'user\' },\'user-2\': { type: \'user\' },...}
//preference:{ \'user-1\': { email: false },  \'user-2\': { email: true }...}
//users和preference的键是一样的,键对应的值都是对象,键的数量也是一样的

var result = _.map(users, function (value, key) {
    return _.extend({id: key}, prefereces[key]);
});

//[ { id: \'user-1\', email: false },{ id: \'user-2\', email: true },...]
console.log(result);

 

■ 对象中键值包含值或函数,取出对象的所有键值对方到一个数组中,键值是函数的执行该函数

var obj = {
    first: \'a\',
    last: \'b\',
    name: function () {
        return this.first + \' \' + this.last;
    },
    age: 22,
    retirement: 65,
    working: function () {
        return this.retirement - this.age;
    }
};

var result1 = _.map(obj, function (value, key) {
    var item = {};
    item[key] = _.isFunction(value) ? obj[key]() : value;
    return item;
});

//[ { first: \'a\' },
//    { last: \'b\' },
//    { name: \'a b\' },
//    { age: 22 },
//    { retirement: 65 },
//    { working: 43 } ]
console.log(result1);

//[ { first: \'a\' },
//    { last: \'b\' },
//    { name: \'a b\' },
//    { age: 22 },
//    { retirement: 65 },
//    { working: 43 } ]
var result2=_.map(obj, function(value, key){
   var item={};
    item[key]= _.result(obj,key);
    return item;
});

console.log(result2);

 

以上,一个是通过isFunction来判断键值是否是函数,一个直接调用result来执行键值函数。

■ 根据键取出一个对象中间对应的函数

 

var object = {
    \'user\': \'fred\',
    \'greet\': function(greeting, punctuation) {
        return greeting + \' \' + this.user + punctuation;
    }
};

var bound = _.bindKey(object, \'greet\',\'hi\');

//hi fred!
console.log(bound(\'!\'));

 

以上,bindKey,根据键greet这个键把它对应的函数取出来。

■ 把对象中的函数取出来放到一个数组中,再invoke它们

 

var obj={
    firstName: \'a\',
    lastName: \'b\',
    first: function(){
        return this.firstName;
    },
    last: function(){
        return this.lastName;
    }
};

var methods =_.map(_.functions(obj),function(item){
    return [_.bindKey(obj, item)];
});

console.log(methods);

//[ \'a\', \'b\' ]
console.log(_.invoke(methods,0));

 

■ 把一个对象中的所有值取出来

 

var _ = require(\'lodash\');

var obj = {
    first: \'a\',
    last: \'b\',
    age:50
};

var result = _.map(_.filter(_.values(obj), _.isString), function(item){
    return \'<strong>\' + item + \'</strong>\';
});

//[ \'<strong>a</strong>\', \'<strong>b</strong>\' ]
console.log(result);

 

不仅通过values把对象的值取出来,还用filter进行了排序,最后还把值包裹到html元素中。

■ 把对象的键值转换成数组元素,再放到更大的数组中去

 

//把首字母转换成大写
function capitalize(s){
    return s.charAt(0).toUpperCase() + s.slice(1);
}

//label接受对象的key
//value接受对象的键值
function format(label, value) {
    return \'<label>\' + capitalize(label) + \':</label>\' +
        \'<strong>\' + value + \'</strong>\';
}

var object = {
    first: \'Julian\',
    last: \'Ramos\',
    age: 43
};

var tempParis =_.pairs(object);
//[ [ \'first\', \'Julian\' ], [ \'last\', \'Ramos\' ], [ \'age\', 43 ] ]
console.log(tempParis);

var result = _.map(tempParis, function(pair){
    return format.apply(undefined, pair);
});

 

以上,pairs方法把对象的键值作为数组的元素,比如[ \'first\', \'Julian\' ],再把[ \'first\', \'Julian\' ]放到一个更大的数组中:[ [ \'first\', \'Julian\' ], ...]


■ 对象的集合,计算某个字段的和,累加的初始值是数字

 

var collection = [
    { ram: 1024, storage: 2048 },
    { ram: 2048, storage: 4096 },
    { ram: 1024, storage: 2048 },
    { ram: 2048, storage: 4096 }
];

var result1 = _.reduce(collection, function(result, item){
    return result+item.ram;
},0);
//6144
console.log(result1);

var result2 = _.reduce(collection, function(result, item){
    return result+item.storage;
},0);
//12288
console.log(result2);

 

以上,0是累加的初始值。

■ 对象的集合,计算某个字段的和, 累加的初始值是对象,类加后的结果也是对象

 

var collection = [
    {hits: 2, misses: 4},
    {hits: 5, misses: 1},
    {hits: 3, misses: 8},
    {hits: 7, misses: 3}
];

var result = _.reduce(collection, function(result, item) {
    return {
        hits: result.hits + item.hits,
        misses: result.misses + item.misses
    };
}, { hits: 0, misses: 0 });

//{ hits: 17, misses: 16 }
console.log(result);

 

■ 自定义累加的算法

 

function add(a,b){
    return a+b;
}

var collection =[
    {wins:34, loses:21},
    {wins:58, loses:12},
    {wins:34, loses:23},
    {wins:40, loses:15},
];

var result1 = _.reduce(_.range(1,6),add);//[ 1, 2, 3, 4, 5 ]
console.log(result1);//15

var result2 =_.reduce(_.pluck(collection,\'wins\'),add);
console.log(result2);//166

 


■ 对象的集合,先过滤,然后自定义求和算法

 

var collection = [
    { name: \'Gina\', age: 34, enabled: true },
    { name: \'Trevor\', age: 45, enabled: false },
    { name: \'Judy\', age: 71, enabled: true },
    { name: \'Preston\', age: 19, enabled: false }
];

var result = _.reduce(_.filter(collection, \'enabled\'), function(result, item){
    result.names.push(item.name);
    result.years+= item.age;
    return result;
},{names:[], years:0});

//{ names: [ \'Gina\', \'Judy\' ], years: 105 }
console.log(result);

 


■ 对象的集合,自定义求和算法,并在算法中过滤

 

var collection = [
    { name: \'Melissa\', age: 28, enabled: true },
    { name: \'Kristy\', age: 22, enabled: true },
    { name: \'Kerry\', age: 31, enabled: false },
    { name: \'Damon\', age: 36, enabled: false }
];

var result = _.reduce(collection, function(result, item) {
    if (item.enabled) {
        result.names.push(item.name);
        result.years += item.age;
    }
    return result;
}, { names: [], years: 0 });

//{ names: [ \'Melissa\', \'Kristy\' ], years: 50 }
console.log(result);

 


■ 对象集合,对象元素中有一个字段是整型数组,这些数组元素相加,把和最小所在的对象打印出来

 

//对象中的一个字段是数值数组
var collection = [
    { name: \'Madeline\', scores: [ 88, 45, 83 ] },
    { name: \'Susan\', scores: [ 79, 82, 78 ] },
    { name: \'Hugo\', scores: [ 90, 84, 85 ] },
    { name: \'Thomas\', scores: [ 74, 69, 78 ] }
];

//对对象item的scores字段所代表的数组数组求和
function score(item) {
    return _.reduce(item.scores, function(result, score) {
        return result + score;
    });
}

var result = _.min(collection, score);

//{ name: \'Madeline\', scores: [ 88, 45, 83 ] }
console.log(result);

 

如果求最大,那就是:

 

var result = _.max(collection, score);

 

■ 对象的集合,对象元素中有个字段是整型号数组,求出每个对象元素整型数组的平均值,放在一个数组中,再求这个数组的平均值

 

function average(items){
    return _.reduce(items, function(result, item){
        return result + item;
    }) / items.length;
}

var collection = [
    { name: \'Anthony\', scores: [ 89, 59, 78 ] },
    { name: \'Wendy\', scores: [ 84, 80, 81 ] },
    { name: \'Marie\', scores: [ 58, 67, 63 ] },
    { name: \'Joshua\', scores: [ 76, 68, 74 ] }
];

//result表示累加之和
//item表示集合中的元素
//index表示集合元素索引
//coll表示集合
var result = _.reduce(collection, function(result, item, index, coll){
    var ave = average(item.scores);
    result.push(ave);

    //如果当前元素的索引是集合中的最后一个元素
    if(index === (coll.length - 1)){
        return average(result);
    }
    return result;
},[]).toFixed(2);

//73.08
console.log(result);

 

■ 删除某个对象中的某些键值对

 

var object = {
    first: \'a\',
    last: \'b\',
    age: 41
},
allowed = [\'first\',\'last\'];

var result = _.reduce(object,function(result, value, key){
    if(_.contains(allowed, key)){
        result[key] = value;
    }
    return result;
},{});

//{ first: \'a\', last: \'b\' }
console.log(result);

var result2 = _.pick(object, allowed);
//{ first: \'a\', last: \'b\' }
console.log(result2);

 

以上,分别通过reduce和pick的方式把对象中的不需要的字段剔除了。


■ 剔除对象中不需要的键值对,并对某些键值进行转换

 

var object = {
    first: \'&lt;strong&gt;Nicole&lt;/strong&gt;\',
    last: \'&lt;strong&gt;Russel&lt;/strong&gt;\',
    age: 26
};


var result = _.transform(object, function(result, value, key) {
    if (_.isString(value)) {
        result[key] = _.unescape(value);
    }
});

//{ first: \'<strong>Nicole</strong>\',
//    last: \'<strong>Russel</strong>\' }
console.log(result);

 

以上,unescape是把键值转换成html元素。

■ 对对象的键值进行转换,再调用对象的原型方法

 

function Person(first, last){
    this.first = first;
    this.last = last;
}

Person.prototype.name = function name(){
    return this.first + \' \' + this.last;
}

var darren = new Person(\'Darren\',\'ji\');

var result = _.transform(darren, function(result, value,key){
   if(_.isString(value)){
       result[key] = value.toString();
   }
}).name();

//Darren ji
console.log(result);

 

■ 对象集合,根据对象元素的某个字段进行分组

 

var collection = [
    { id: _.uniqueId(\'id-\'), position: \'absolute\', top: 12 },
    { id: _.uniqueId(\'id-\'), position: \'relative\', top: 20 },
    { id: _.uniqueId(\'id-\'), position: \'absolute\', top: 12 },
    { id: _.uniqueId(\'id-\'), position: \'relative\', top: 20 }
];

var result = _.groupBy(collection, \'position\');

//{ absolute:
//    [ { id: \'id-1\', position: \'absolute\', top: 12 },
//        { id: \'id-3\', position: \'absolute\', top: 12 } ],
//        relative:
//    [ { id: \'id-2\', position: \'relative\', top: 20 },
//        { id: \'id-4\', position: \'relative\', top: 20 } ] }
console.log(result);


var result2 = _.indexBy(collection, \'id\');

//{ \'id-1\': { id: \'id-1\', position: \'absolute\', top: 12 },
//    \'id-2\': { id: \'id-2\', position: \'relative\', top: 20 },
//    \'id-3\': { id: \'id-3\', position: \'absolute\', top: 12 },
//    \'id-4\': { id: \'id-4\', position: \'relative\', top: 20 } }
console.log(result2);

 

■ 为map方法绑定上下文

 

var app = {
    states: [
        \'running\',
        \'off\',
        \'paused\'
    ],
    machines: [
        { id: _.uniqueId(), state: 1 },
        { id: _.uniqueId(), state: 0 },
        { id: _.uniqueId(), state: 0 },
        { id: _.uniqueId(), state: 2 }
    ]
};

var mapStates = _.partialRight(_.map, function(item){
    return _.extend({state: this.states[item.state]}, _.pick(item,\'id\'));
},app);

var result = mapStates(app.machines);

//[ { state: \'off\', id: \'1\' },
//    { state: \'running\', id: \'2\' },
//    { state: \'running\', id: \'3\' },
//    { state: \'paused\', id: \'4\' } ]
console.log(result);

 

以上,partialRight方法的第三个参数app是map方法的上下文。

■ 为reduce方法绑定上下文

 

var collection = [ 12, 34, 53, 43 ],
    settings = { tax: 1.15 },
    applyTax = _.partialRight(_.reduce, function(result, item) {
        return result + item * this.tax;
    }, 0, settings);


//163.30
console.log(applyTax(collection).toFixed(2));

 

■ 对象集合,更改对象某个字段的值,类似泛型

 

//this作为上下文对象有prop和value字段
//this的prop键值决定哪个字段需要实施加法
//item在这里会传入集合元素
function add(item){
    var result = _.clone(item);
    result[this.prop] += this.value;
    return result;
}

function upper(item){
    var result = _.clone(item);
    result[this.prop]=result[this.prop].toUpperCase();
    return result;
}

var collection = [
    { name: \'Gerard\', balance: 100 },
    { name: \'Jean\', balance: 150 },
    { name: \'Suzanne\', balance: 200 },
    { name: \'Darrell\', balance: 250 }
];

var mapAdd = _.partial(_.map, collection, add),
    mapUpper = _.partial(_.map, collection, upper);

//[ { name: \'Gerard\', balance: 150 },
//    { name: \'Jean\', balance: 200 },
//    { name: \'Suzanne\', balance: 250 },
//    { name: \'Darrell\', balance: 300 } ]
console.log(mapAdd({ prop: \'balance\', value: 50 }));


//[ { name: \'GERARD\', balance: 100 },
//    { name: \'JEAN\', balance: 150 },
//    { name: \'SUZANNE\', balance: 200 },
//    { name: \'DARRELL\', balance: 250 } ]
console.log(mapUpper({ prop: \'name\'}));

 


■ 对象集合,对某个字段求和,类似泛型

 

function sum(a,b){
    return a+b[this.prop];
}

var collection = [
    { low: 40, high: 70 },
    { low: 43, high: 83 },
    { low: 39, high: 79 },
    { low: 45, high: 74 }
];

var reduceSum = _.partial(_.reduce, collection, sum, 0);

//167
console.log(reduceSum({ prop: \'low\' }));

 

■ 对象集合,先为对象元素增加一个字段,再对所有对象求和,求和自定义算法

 

var collection = [
    { name: \'Wade\', balance: 100 },
    { name: \'Donna\', balance: 125 },
    { name: \'Glenn\', balance: 90 },
    { name: \'Floyd\', balance: 110 }
], bonus = 25;

//为每个集合元素增加了一个bonus字段
var mapped = _.map(collection, function(item) {
    return _.extend({
        bonus: item.balance + bonus
    }, item);
});

//求和
//item是集合中的元素
//index是集合中元素的索引
//coll是集合
//result是累计结果
var result = _.reduce(mapped, function(result, item, index, coll) {
        result += (item.bonus - item.balance) / item.bonus;

        //如果累加到最后一个集合元素
        if (index === (coll.length - 1)) {
            result = result / coll.length * 100;
        }
        return result;
    }, 0).toFixed(2) + \'%\';

//19.23%
console.log(result);

 

参考资料:lodash essentials

 

未完待续~~

 

分类:

技术点:

相关文章:

  • 2021-06-22
  • 2022-12-23
  • 2021-11-04
  • 2022-01-08
  • 2022-02-28
  • 2022-12-23
  • 2021-04-08
  • 2022-12-23
猜你喜欢
  • 2021-08-07
  • 2022-02-19
  • 2021-10-16
  • 2022-12-23
  • 2021-06-30
  • 2021-05-31
  • 2022-12-23
相关资源
相似解决方案