Underscore 源码解读 - Array Functions

Underscore - Array Functions

initial(数组去尾)

语法:_.initial( array [ , n ] )

删除数组中后 n 个元素,返回新数组,n 默认为 1。

源码:
1
2
3
4
_.initial = function(array, n, guard) {
// 复制数组前 length - n 个元素,存入新数组。
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};

rest(数组掐头)

别名:tail, drop
语法:_.rest( array [ , index ] )

删除数组中前 n 个元素,返回新数组,n 默认为 1。

源码:
1
2
3
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, n == null || guard ? 1 : n);
};

first(数组取头)

别名:head, take
语法:_.first( array [ , n ] )

返回数组中前 n 个元素。

源码:
1
2
3
4
5
6
7
8
_.first = _.head = _.take = function(array, n, guard) {
// 数组为空 或者 数组长度小于 1,则返回 undefined。
if (array == null || array.length < 1) return void 0;
// n 为空 或者 guard 为 "真值",则返回数组中第一个元素的值。
if (n == null || guard) return array[0];
// 调用 initial() 方法(数组去尾)。
return _.initial(array, array.length - n);
};
注意:

使用 void 0 来返回 undefined 值,因为 JavaScriptundefined 不是关键字,可以作为变量名。

last(数组取尾)

语法:_.last( array [ , n ] )

返回数组中后 n 个元素。

源码:
1
2
3
4
5
6
7
_.last = function(array, n, guard) {
if (array == null || array.length < 1) return void 0;
// n 为空 或者 guard 为 "真值",则返回数组中最后一个元素的值。
if (n == null || guard) return array[array.length - 1];
// 调用 rest() 方法(数组掐头)。
return _.rest(array, Math.max(0, array.length - n));
};

flatten(数组扁平化)

语法:_.flatten( array [ , shallow ] )

将一个多维数组转换为一维数组,shallow 为 true 则只解套当前层。

1
2
3
4
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, false);
};

uniq(数组去重)

别名:unique
语法:_.uniq( array [ , isSorted ] [ , iteratee ] )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
// 如果 isSorted 是非布尔值,表示省略,默认值为 false,后面的参数往前移一位。
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
// 如果 iterratee 不为空,则 赋予其 callback 对象。
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
for (var i = 0, length = getLength(array); i < length; i++) {
// value 为数组的原始值,computed 为计算值。
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {// 数组已排序情况下,
// 第一次循环,value 直接存入 result,
// 第二次起,将 seen 与 computed(当前值) 比较,不相等则将 value 存入 result,
if (!i || seen !== computed) result.push(value);
// 把 computed(当前值) 存入 seen,
// 这里将 seen 作为存放上一次循环中 computed 的临时变量用。
seen = computed;
} else if (iteratee) {
// 如果 seen 中没有 computed,则把 computed 存入 seen,value 存入 result。
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
// 如果 result 中没有 value,则把 value 存入 result
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};

union(数组并集)

语法:_.union( *arrays )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
_.union = restArgs(function(arrays) {
return _.uniq(flatten(arrays, true, true));
});
/*
* 1, 调用 restArgs 方法
* 传入 [1,2,3],[2,3,4],[3,4,5] 进行数组叠加
* 返回 [[1,2,3],[2,3,4],[3,4,5]]
*
* 2, 调用 flatten 方法
* 传入 [[1,2,3],[2,3,4],[3,4,5]] 进行扁平化,
* 返回 [1,2,3,2,3,4,3,4,5]
*
* 3, 调用 uniq 方法
* 传入 [1,2,3,2,3,4,3,4,5] 进行数组去重
* 返回 [1,2,3,4,5]
*/
_.union([1,2,3],[2,3,4],[3,4,5]); // [1, 2, 3, 4, 5]

intersection(数组交集)

语法:_.intersection( *arrays )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
_.intersection = function(array) {
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = getLength(array); i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
var j;
for (j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};

compact

语法:_.compact( array )

difference

语法:_.difference( array, *others )

without

语法:_.without( array, *values )
源码:
1
2
3
_.without = restArgs(function(array, otherArrays) {
return _.difference(array, otherArrays);
});

zip

语法:_.zip( *arrays )

unzip

语法:_.unzip( *arrays )

object

语法:_.object( list [ , values ] )

indexOf

语法:_.indexOf(array, value [ , isSorted])

lastIndexOf

语法:_.lastIndexOf( array, value [ , fromIndex ] )

sortedIndex

语法:_.sortedIndex( list, value [ , iteratee [ , context ] ] )

findIndex

语法:_.findIndex( array, predicate [ , context ] )

findLastIndex

语法:_.findLastIndex( array, predicate [ , context ] )

range

语法:_.range( [ start ] , stop [ , step ] )