前情提要1 : lodash中文学习拾零之Array篇
前情提要2:lodash 中文学习拾零之 Chain篇
3、Collection(集合)与Array(数组)的区别
对于lodash的初学者而言,可能一下子搞不清楚为什么lodash提供了Array和Collection两类方法?表面上看起来好像这两套方法有些地方是可以互换的,那么我们就进一步来澄清什么是Collection方法,什么是Array方法。
在lodash中,Collection是一个抽象的概念,指的是那些我们准备用来迭代的Javascript object,可以是 数组、字符串或者object对象,至于这些数据类型之间的差别细节,则被lodash隐藏起来了,作为开发者你不用操心。
而lodash的 Array方法则没有那么抽象,它们要求你处理的就是实实在在的数组。从这个意义上讲,即便Array方法没有显式的检查你提交的数据类型,但是它们要求你提交的数据得有数值型length属性(a numerical length property)。
实际上,在大部分时候,你并不需要严格得区分 arrays 和 collections 之间的差别,因为你面对的大多数collections都是以数组的形式出现的,只有在比较少的情况下,你会面临着差别 。所以你只要记住,Array方法是严格要求数据类型(有数值型length属性)的就行了。
3.1 遍历collection元素
3.1.1 .forEach
_.forEach是处理Collection最基础的函数了,下面这个例子非常简单,就是告诉你forEach是如何进行迭代(循环)的:
var collection = [
'红',
'黄',
'蓝',
'绿'
];
_.forEach(collection, function(name) {
console.log(name);
});
// →
// 红
// 黄
// 蓝
// 绿
_.forEach有三个参数,第一个参数是要处理的collection,第二个参数是迭代器(以匿名函数的形式出现),第三个参数是 The this binding of iteratee(可以理解为迭代器里的this绑定的方法).
_.forEach文档定义如下:
Aliases(别名):
_.eachArguments(参数):
1、collection (Array|Object|string): The collection to iterate over.
2、[iteratee=_.identity] (Function): The function invoked per iteration.
3、 [thisArg] (*): The this binding of iteratee.
//例子
var collection = [100,200,300,400];
_.forEach(collection, function(value) {
console.log(this.sqrt(value)); //对collection中的每个值开方
},
Math); //本例中thisArg绑定了Math的方法
//10
//14.142135623730951
//17.320508075688775
//20
当迭代发生的时候,每轮到一个元素都激活一次迭代器,迭代器有三个参数:
(1)被迭代的元素,(2)该元素的index或者key,(3)collection。
在迭代器返回false值时,允许整个迭代过程提早结束,如下面的例子:
var myCollection = [
'阿猫',
'阿狗',
'小黑',
'阿花'
];
_.forEach(myCollection, function(name, index, collection) {
if (name === '小黑') {
console.log('小黑的index: ' + index);
console.log(collection[index]);
return false;
}
});
// → 小黑的index: 1
// → 小黑
3.1.2 .forEachRight
与_.forEach的执行方向相反,从最右侧的元素先开始进行迭代:
_([1, 2]).forEachRight(function(n) {
console.log(n);
}).value();
// → 2
// → 1
3.3 排序
排序是我们对collection进行操作时会经常遇到的问题,javascript自带的sort()、reverse()之类的函数,远远不能满足我们的需求。
3.3.1 .sortBy
_.sortBy会根据迭代器对输入的collection的每个数组元素进行计算后排序(升序)并生成一个新的数组,同时不会影响原collection的排序(这一点与原生的sort 不同)。
.sortBy有三个参数,与.forEach相同。
迭代器本身还有三个参数(value, index|key, collection),也与.forEach的迭代器相同。
//_.sortBy例子
_.sortBy([1, 2, 3], function(n) {
return Math.sin(n); //直接在迭代器中使用Math
});
// → [3, 1, 2]
_.sortBy([1, 2, 3], function(n) {
return this.sin(n); //在迭代器内用this绑定了Math
}, Math);