Underscore 中间 flatten 相关的方法之前一直不是很理解,现在完全搞懂了,稍微说一下。
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
| var flatten = function(input, shallow, strict, output) { output = output || []; var idx = output.length; for (var i = 0, length = getLength(input); i < length; i++) { var value = input[i]; if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { if (shallow) { var j = 0, len = value.length; while (j < len) output[idx++] = value[j++]; } else { flatten(value, shallow, strict, output); idx = output.length; } } else if (!strict) { output[idx++] = value; } } return output; };
|
这个方法不难看懂,作用是将input平铺展开,如果 shallow
为 true
,则只展开一层。
1 2
| _.flatten([1, 2, [3], [[4, [5]]]]) _.flatten([1, 2, [3], [[4, [5]]]], true)
|
这里的 strict
参数就是之前一直卡住的原因,就是下面这个地方:
1 2 3 4 5 6 7 8 9 10 11
| _.without = restArgs(function(array, otherArrays) { return _.difference(array, otherArrays); }); _.difference = restArgs(function(array, rest) { rest = flatten(rest, true, true); return _.filter(array, function(value){ return !_.contains(rest, value); }); });
|
这是两个方法,那时候想 without
方法调用的时候, otherArrays
是一个数组了,到 difference
方法的时候,这个数组去调用 flatten
方法的时候不是会出问题吗?
1
| _.flatten([1, 2, 3], true, true)
|
脑子里面就这样想…卡了好久,等我基本看了全部源码才会过来看才理解了。
difference
方法的 restArgs
很重要,他们两个是各自独立的方法,但是 without
可以共用 difference
的逻辑。
上面那样子理解是有问题的,因为在 without
方法中 otherArrays
如果是[1, 2, 3],到了 flatten
调用的时候因为 restArgs
的关系他变成了 [[1, 2, 3]],调用最后返回结果[1, 2, 3]。然后我就纳闷了,加了一层又解除这是何解…
不过抛开 without
方法去看 difference
方法就能理解了。
1 2 3 4 5 6 7 8
| _.without([1, 2, 3, 4, 5, 6], 1, 2, 3); _.difference([1, 2, 3, 4, 5, 6], [1, 2], [3]);
|
所以其实 difference
方法的 restArgs
虽然对与 without
方法中的调用是多余的,但是作为一个独立的方法,他还是有必要的。
上面注释应该说的很清楚了,完。
其实只是我自己没看清楚而已,也不难。这个地方的很多方法比如 union
, intersection
等等都是集合的相关操作。比如 difference
就是差集,union
就是并集,而intersection
就是交集。