lodash源码(2)
1.flatten 对深层嵌套数组的抹平
_.flatten([1, [2, 3, [4]]]);
* // => [1, 2, 3, [4]]
*
* // using `isDeep`
* _.flatten([1, [2, 3, [4]]], true);
* // => [1, 2, 3, 4]
在方法中使用了递归的算法: 1.递归的产生条件 2.递归的结束条件 递归就是数学的归纳法,采用数据结构的栈的模式
自己做的递归的一个算法(原lodash涉及了很多个文件,这里只是提供了一个简单的思路.并没有对数据类型做更详细的判断)
function baseFlatten(array, isDeep, isStrict, result) { //baseFlatten中传入result是为了在递归中,保留以前的数据
result || (result = []); //如果没有传入result则默认的是空的[]
var index = -1,
length = array.length;
while (++index < length) {
if (Array.isArray(array[index])) { //递归的条件
var value = array[index];
if (isDeep) {
baseFlatten(value, isDeep, isStrict, result);
}
} else {
result.push(array[index]) //递归的结束
}
}
return result;
}
2.indexOf 求索引
js使用原生的indexOf来判断变量在数组中的位置
但是在性能上与while循环或者for循环相比差的比较多
var i = 0;
var arr = [];
while (i++ < 2000000) {
arr.push(i + ''+i );
}
var old = Date.now();
console.log(arr.indexOf(''));
console.log(old, Date.now(), Date.now() - old);
function baseIndexOf(array, value) {
var index = 0,
length = array.length;
var old1 = Date.now();
while (++index < length) {
if (array[index] === value) {
console.log(old1, Date.now(), Date.now() - old1,index);
return index;
}
}
console.log(old1, Date.now(), Date.now() - old1,i);
return -1;
}
baseIndexOf(arr,'');
function baseIndexOf(array, value) {
var length = array.length;
var old1 = Date.now();
for(var i = 0;i <length;i++){
if (array[i] === value) {
console.log(old1, Date.now(), Date.now() - old1,i);
return i;
}
}
console.log(old1, Date.now(), Date.now() - old1,i);
return -1;
}
baseIndexOf(arr,'');
/*
-1
1479287884122 1479287884172 50
1479287884174 1479287884199 25 2000000
1479287884199 1479287884224 25 2000000
*/
3.pull方法,移除某多个元素,其中使用了原生的splice方法,而对于slice方法,lodash则改写了这个方法,使用while循环,空数组赋值的方式.pull传入的参数是元素.pullAt是传入的索引.
function pull() {
var args = arguments,
array = args[0];
if (!(array && array.length)) {
return array;
}
var index = 0,
indexOf = baseIndexOf,
length = args.length;
while (++index < length) { //主循环,对arguments进行主循环,针对于传入多个要移除的元素 _.pull(array, 2, 3);
var fromIndex = 0,
value = args[index];
while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { // var array = [1, 2, 3, 1, 2, 3] 需要多次循环,如果有这个值,则index > -1,如果没有这个值则index = -1则内循环停止,接着进下一个主循环.
splice.call(array, fromIndex, 1);
}
}
return array;
}
4.pullAt pull出传入的索引,内部实现采用splice方法,splice方法会更改原数组.
例如:
var array = [5, 10, 15, 20];
var evens = _.pullAt(array, 1, 3);
源码:
function basePullAt(array, indexes) {
var length = array ? indexes.length : 0;
while (length--) {
var index = indexes[length];
if (index != previous && isIndex(index)) {
var previous = index;
splice.call(array, index, 1);
}
}
return array;
}
/*
根据索引去除数组中某个数据,没有很方便的方法,只能使用splice方法,通过索引来删除某个值.
原数组只剩下 删除后的 新的则是返回的数组内容
*/
5.remove 作用与pull pullAt remove 是一样的,只是传入的参数不同,remove传入的参数是fucntion(){}
function remove(array, predicate, thisArg) {
var result = [];
if (!(array && array.length)) {
return result;
}
var index = -1,
indexes = [],
length = array.length;
predicate = baseCallback(predicate, thisArg, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result.push(value); //因为pullAt中调用了splice方法,这里返回的结果是符合function条件的.通过这种方式返回了.注意返回结果别搞混了.
indexes.push(index); //获取到索引的集合,然后通过索引的集合调用pullAt方法
}
}
basePullAt(array, indexes);
return result;
}