lodash用法系列(6),函数种种
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: 'Ronnie', age: 43 },
{ name: 'Ben', age: 19 },
{ name: 'Sharon', age: 25 },
{ name: 'Melissa', age: 29 }
]; //返回name键值组成的数组
function collectionNames(){
//依赖于变量
//name是hardcode
return _.map(collection, 'name');
} //coll形参,输入集合
//prop形参,输入集合对象的某个字段
//map中的参数完全依赖形参,coll, prop泛型
function inderectionNames(coll, prop){
return _.map(coll, prop);
} //coll形参,输入集合
//coll泛型
function genericCollNames(coll){
return _.map(coll, 'name');
} //prop形参,输入集合对象的某个字段
//prop泛型
function genericPropNames(prop){
return _.map(collection, prop);
} //[ 'Ronnie', 'Ben', 'Sharon', 'Melissa' ]
console.log(collectionNames()); //[ 'Ronnie', 'Ben', 'Sharon', 'Melissa' ]
console.log(inderectionNames(collection, 'name')); //[ 'Ronnie', 'Ben', 'Sharon', 'Melissa' ]
console.log(genericCollNames(collection)); //[ 'Ronnie', 'Ben', 'Sharon', 'Melissa' ]
console.log(genericPropNames('name'));
■ 函数的参数都不是静态的、固定的,但可以到arguments中提取
function insert(coll, callback){
var toInsert;
//也就是callback这个参数是optional的
if(_.isFunction(callback)){
toInsert= _.slice(arguments,2);//截掉insert参数中coll, callback这2个实参
}else{
toInsert= _.slice(arguments,1)
callback= _.identity;//_.identity是lodash回调函数的默认值
}
_.each(toInsert, function(item){
//把加入的元素放到coll集合中合适的位置
coll.splice(_.sortedIndex(coll, item, callback),0, item);
});
return coll;
}
var collection=_.range(1,11);
var result = insert(collection,8.4);
//[ 1, 2, 3, 4, 5, 6, 7, 8, 8.4, 9, 10 ]
console.log(result);
■ 函数的参数不是静态的、固定的,输入部分实参
以上在调用函数的时候是把所有的实参给了函数,而在lodash中,还可以分步输入实参。
//接受两个形参
var greet = function (greeting, name) {
return greeting + ' ' + name;
} //先输入第一个实参
var sayHello = _.partial(greet, 'hello'); //再输入第二个实参
//hello darren
console.log(sayHello('darren')); //输入两个实参,第一个用占位符
var greetJack = _.partial(greet, _, 'jack'); //hi jack
console.log(greetJack('hi'));
以上,greet函数接受2个形参,但我们在实际使用过程中,先输入一个实参,再输入其它实参。
如果先输入第二个实参,就使用partialRight方法。如果使用partialRight而不输入第二个实参,只输入第一个实参,那第二个实参需要用占位符。
与parital类似的还有一个方法使curry:
var add = function (a, b) {
return a + b;
}
var c1 = _.curry(add);
var c2 = c1(5);
var result = c2(6);
//
console.log(result);
partial和curry的共同点都是需要把实参凑齐了才能执行方法。不同点是:parital似乎把2个参数交给了一个人,一个人先后拿到所有的实参;curry似乎是把不同的参数交给了不同的人,拿2个实参为例,拿到第一个实参交给一个人c1,c1说我拿了实参5告诉c2,c2知道后有拿了参数6,2个实参拿齐后,由c2执行方法。
■ 自定义的函数作为回调函数
var YEAR_MILLISECONDS = 31560000000;
function validItem(item){
return item.age > 21 &&
_.isString(item.first) &&
_.isString(item.last);
}
var invalidItem = _.negate(validItem);
function computed(item) {
return _.extend({
name: _.result(item, 'first', '') + ' ' +
_.result(item, 'last', ''),
yob: new Date(new Date() - (YEAR_MILLISECONDS * item.age))
.getFullYear()
}, item);
}
var collection = [
{ first: 'Roderick', last: 'Campbell', age: 56 },
{ first: 'Monica', last: 'Salazar', age: 38 },
{ first: 'Ross', last: 'Andrews', age: 45 },
{ first: 'Martha', age: 51 }
];
console.log(_.every(collection, validItem));//false
//[ { first: 'Roderick', last: 'Campbell', age: 56 },
// { first: 'Monica', last: 'Salazar', age: 38 },
// { first: 'Ross', last: 'Andrews', age: 45 } ]
console.log(_.filter(collection, validItem));
//{ first: 'Martha', age: 51 }
console.log(_.find(collection, invalidItem));
//[ { name: 'Roderick Campbell',
// yob: 1959,
// first: 'Roderick',
// last: 'Campbell',
// age: 56 },...]
console.log(_.map(collection, computed));
■ 把过滤封装到一个函数中
function byName(coll, name, take) {
return _(coll)
.filter({ name: name })
.take(_.isUndefined(take) ? 100 : take)
.value();
}
var collection = [
{ name: 'Theodore', enabled: true },
{ name: 'Leslie', enabled: true },
{ name: 'Justin', enabled: false },
{ name: 'Leslie', enabled: false }
];
byName(collection, 'Leslie');
byName(_.filter(collection, 'enabled'), 'Leslie');
byName(_(collection).filter('enabled'), 'Leslie');
以上,把过滤封装到了byName方法中,并且在该方法内返回值,即直接调用了方法。
■ 把链式封装到一个函数中
function sort(coll, prop, desc){
var wrapper = _(coll).sortBy(prop);
return desc? wrapper.reverse() : wrapper;
}
var collection = [
{ first: 'Bobby', last: 'Pope' },
{ first: 'Debbie', last: 'Reid' },
{ first: 'Julian', last: 'Garcia' },
{ first: 'Jody', last: 'Greer' }
];
var result = sort(collection,'first').value();
//[ { first: 'Bobby', last: 'Pope' },
// { first: 'Debbie', last: 'Reid' },
// { first: 'Jody', last: 'Greer' },
// { first: 'Julian', last: 'Garcia' } ]
console.log(result);
var result2=sort(collection,'last')
.takeRight(2)
.pluck('last') //获取某个字段的值放在数组中
.value();
//[ 'Pope', 'Reid' ]
console.log(result2);
以上,把链式封装到了sort方法中,但在该方法内没有返回值,该方法可以看做是链式的一个wrapper。
■ 补充:indexBy的用法
var keyData = [
{ 'dir': 'left', 'code': 97 },
{ 'dir': 'right', 'code': 100 }
]; var result1= _.indexBy(keyData,'dir'); //把dir字段对应的键值作为键,把集合元素作为键值
//{ left: { dir: 'left', code: 97 },
// right: { dir: 'right', code: 100 } }
console.log(result1);
■ 把几个方法合成起来
function enabledIndex(obj){
return _.transform(obj, function(result, value, key){
result[key]= _.result(value, 'enabled',false);
});
}
var collection = [
{ name: 'Claire', enabled: true },
{ name: 'Patricia', enabled: false },
{ name: 'Mario', enabled: true },
{ name: 'Jerome', enabled: false }
];
//实际上indexByName接受2个形参,一个是集合,一个是字段
//indexByName的返回结果是以name属性值为key,集合元素作为value
//{ Claire: { name: 'Claire', enabled: true },
// Patricia: { name: 'Patricia', enabled: false },
// Mario: { name: 'Mario', enabled: true },
// Jerome: { name: 'Jerome', enabled: false } }
var indexByName=_.partialRight(_.indexBy, 'name'),
//把第一个参数collection传给第一个方法IndexByName
//第一个方法的返回值作为第二个方法的实参
enabled=_.partial(_.flow(indexByName, enabledIndex), collection);
//{ Claire: true, Patricia: false, Mario: true, Jerome: false }
console.log(enabled());
以上,通过flow方法把indexByName和enabledIndex方法合成了起来,并且,第一个方法的返回值作为第二个方法的实参。
■ 合成函数,并作为回调函数
var collection = [
{ first: 'Andrea', last: 'Stewart', age: 28 },
{ first: 'Clarence', last: 'Johnston', age: 31 },
{ first: 'Derek', last: 'Lynch', age: 37 },
{ first: 'Susan', last: 'Rodgers', age: 41 }
]; var minimal=_.flow(_.identity, _.partialRight(_.pick, ['last','age'])); var result=_.map(collection, minimal); //[ { last: 'Stewart', age: 28 },
// { last: 'Johnston', age: 31 },
// { last: 'Lynch', age: 37 },
// { last: 'Rodgers', age: 41 } ]
console.log(result);
■ 合成函数,控制链式的过程
function sorted(wrapper){
return _(wrapper).sortBy();
}
function rejectOdd(wrapper){
return _(wrapper).reject(function(item){
return item%2;
});
}
var sortedEvens=_.flow(sorted, rejectOdd),
evensSorted=_.flow(rejectOdd, sorted, _.partialRight(_.result, 'value')),
collection=_.shuffle(_.range(1,11));
var result=sortedEvens(collection)
.reverse()
.value();
//[ 10, 8, 6, 4, 2 ]
console.log(result);
以上,sorted和sortedEvens方法接收的是wrapper,正是因为是wrapper,所以在flow中可以改变这些wrapper的顺序,即控制链式过程。
■ 在函数的方法中显示使用链式
function validThru(next, value){
return value && next;
}
function User(first, last, age){
this.first=first;
this.last=last;
this.age=age;
}
User.prototype.valid = function(){
return _.chain(this.first) //一旦显式调用chain方法,意味着接下来那些返回值的函数返回wrapper
.isString()
.thru(_.partial(validThru, this.last))//validThru相当于thru的回调函数
.isString()
.thru(_.partial(validThru, this.age))
.isFinite()
.value();
}
var result = new User('orlando','Olson',25).valid();
console.log(result);
■ 自定义内置方法average
//自定义average方法
_.mixin({average:function(coll, callback){
return _(coll)
.map(callback)
.reduce(function(result, item){
return result +item;
}) / _.size(coll);
}});
var collection = [
{ name: 'Frederick', age: 41, enabled: true },
{ name: 'Jasmine', age: 29, enabled: true },
{ name: 'Virgil', age: 47, enabled: true },
{ name: 'Lila', age: 22, enabled: false }
];
var result = _.average(collection, 'age');
//34.75
console.log(result);
参考资料:lodash essentials
本系列结束☺
lodash用法系列(6),函数种种的更多相关文章
- lodash用法系列(3),使用函数
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(5),链式
Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...
- lodash用法系列(4),使用Map/Reduce转换
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 ...
- Case when 的用法,简单Case函数
Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值. 语法: CASE search_expression WHEN expression1 THEN result ...
- 智能合约语言 Solidity 教程系列3 - 函数类型
Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...
- Go基础系列:函数(2)——回调函数和闭包
回调函数和闭包 当函数具备以下两种特性的时候,就可以称之为高阶函数(high order functions): 函数可以作为另一个函数的参数(典型用法是回调函数) 函数可以返回另一个函数,即让另一个 ...
- JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
本篇主要体验函数参数个数不确定情况下的一个解决方案.先来看一段使用函数作为参数进行计算的实例. var calculate = function(x, y, fn) { return fn(x, y) ...
随机推荐
- Linux Core Dump【转】
转自:http://www.cnblogs.com/hazir/p/linxu_core_dump.html 当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中 ...
- jstack查看Java堆栈信息
命令 jps 查看进程id jstack 1234 查看该进程的线程堆栈信息 对于每个线程,都有如下信息: 线程名,如“main”线程属性(如果是Daemon线程,会有Daemon标识,否则,什么都没 ...
- CentOS下配置MySQL允许root用户远程登录
1.常用命令: 安装上传下载文件命令yum install lrzsz安装webget工具yum -y install wget ----------------------------------- ...
- 集合类List、Set、Map的区别、联系和遍历方式
说集合之前,先说说数组和集合: 1.数组长度是固定的,当超过容量后会在内存中重新创建一个原来数组1.5倍长度的新数组,再把元素存进去:数组既可以存储基本数据类型,又可以存储引用数据类型. 2.集合长度 ...
- 在内部局域网内搭建HTTPs
在内部局域网内搭建HTTPs 配置环境 Windows版本:Windows Server 2008 R2 Standard Service Pack 1 系统类型: 64 位操作系统 内存 ...
- Python 爬虫入门之爬取妹子图
Python 爬虫入门之爬取妹子图 来源:李英杰 链接: https://segmentfault.com/a/1190000015798452 听说你写代码没动力?本文就给你动力,爬取妹子图.如果 ...
- CF1064B 【Equations of Mathematical Magic】
题目要求解$a-(a\oplus x)-x=0$的解$x$的个数 移项得$a-x=a\oplus x$ $a$的二进制形式,应该是一个$01$串,异或的过程是不能影响到两个不同的位的,所以我们按位考虑 ...
- kafka查看消费数据
一.如何查看 在老版本中,使用kafka-run-class.sh 脚本进行查看.但是对于最新版本,kafka-run-class.sh 已经不能使用,必须使用另外一个脚本才行,它就是kafka-co ...
- Windows下安装Python requests模块
在使用自己写的或者别人的python小工具时可能会出现类似ImportError: No module named Requests的问题: D:\tool\python\fuzz>Fuzz.p ...
- CI框架中集成CKEditor编辑器的教程
CKEditor是在很多开发过程中都会用到的一个富文本编辑器,那么如何在CI框架中使用它呢?这里介绍了在CI下使用CKEditor的方法,版本比较低,是在CI 1.7.3下使用fckeditor 2. ...