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\n'; var result1 = _(string)
.slice()
.value(); //[ 'a', 'b', 'c', '\n' ]
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);// var result2 = _(object)
.omit('first')
.size(); console.log(result2);//
■ size运用到数组上数的是元素的数量
var array = _.range(10); var result =_(array)
.drop(5)
.size(); console.log(result);//
■ 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);//
以上,通过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);//
■ 获取两个数组的差集
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
未完待续~~
lodash用法系列(5),链式的更多相关文章
- lodash用法系列(6),函数种种
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(4),使用Map/Reduce转换
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(3),使用函数
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(2),处理对象
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(1),数组集合操作
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- iOS开发技巧系列---使用链式编程和Block来实现UIAlertView
UIAlertView是iOS开发过程中最常用的控件之一,是提醒用户做出选择最主要的工具.在iOS8及后来的系统中,苹果更推荐使用UIAlertController来代替UIAlertView.所以本 ...
- MySQL中间件之ProxySQL(11):链式规则( flagIN 和 flagOUT )
返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html 1.理解链式规则 在mysql_query_rules表中,有两个特殊 ...
- ProxySQL(11):链式规则( flagIN 和 flagOUT )
文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9350631.html 理解链式规则 在mysql_query_rules表中,有两个特殊字段"fl ...
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
随机推荐
- mysql percona安装
注:此方式目前安装存在问题(弃用此方式) 1.在官方网站下载percona XtraBackup https://www.percona.com/downloads/XtraBackup/LATES ...
- 设置linux的console为串口【转】
转自:http://blog.chinaunix.net/uid-27717694-id-4074219.html 以Grub2为例:1. 修改文件/etc/default/grub #显示启动菜 ...
- 测试开发之Django——No4.Django中前端框架的配置与添加
我们在开发一个web项目的时候,虽然我们不是专业开发,但是我们也想要做出来一个美美的前端页面. 这种时候,百度上铺天盖地的前端框架就是我们的最好选择了. 当然,在网上直接下载的框架,我们是不能直接用的 ...
- Android Service总结06 之AIDL
Android Service总结06 之AIDL 版本 版本说明 发布时间 发布人 V1.0 初始版本 2013-04-03 Skywang 1 AIDL介绍 AIDL,即And ...
- 更换网页tab标题图标
在首页HTML文件中,加入link命令,<link>是放在<head>与</head>之间 例如下面这样: <HEAD><link rel = & ...
- *使用配置类定义Codeigniter全局变量
之前提到的 CodeIgniter 引入自定义公共函数 这篇文章提到了公共函数实现,全局的变量也可以借助 helper 函数来实现.不过,更为合适的方式可能要属用配置类定义了. CodeIgniter ...
- Java编程的逻辑 (62) - 神奇的序列化
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
- 【Java】 大话数据结构(14) 排序算法(1) (冒泡排序及其优化)
本文根据<大话数据结构>一书,实现了Java版的冒泡排序. 更多:数据结构与算法合集 基本概念 基本思想:将相邻的元素两两比较,根据大小关系交换位置,直到完成排序. 对n个数组成的无序数列 ...
- Android 短信拦截及用途分析
监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...
- [HDU4348]To the moon(主席树+标记永久化)
学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间. 这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put ...