微博上看到有人说手工实现个_.flatten(将[1,[2,[2,1]],2]变为[1,2,2,1,2])就可以给他发简历了,发简历没什么兴趣,倒是可以试着实现一个。想了想其实这个不难,我的实现如下:
var flatten = function(arr) { var index = arguments[1] || 0; var destArr = arr.slice(0, index).concat(arr[index]).concat(arr.slice(index + 1)); return index === arr.length ? arr: arguments.callee(destArr, ++index); }
原理就是对数组进行concat生成新的数组,concat的时候可以减少数组的维数。后面看了微博上其他人的实现,顿时觉得自己好2。直接concat就行了,下面是别人的实现:
Array.prototype.flatten = function() { var flattened = Array.prototype.concat.apply([], this); if (flattened.length == this.length) return flattened; else return flattened.flatten(); }
附上underscore的_.flatten
_.flatten = function(array, shallow) { // 迭代数组中的每一个元素, 并将返回值作为demo传递给下一次迭代 return _.reduce(array, function(memo, value) { // 如果元素依然是一个数组, 进行以下判断: // - 如果不进行深层合并, 则使用Array.prototype.concat将当前数组和之前的数据进行连接 // - 如果支持深层合并, 则迭代调用flatten方法, 直到底层元素不再是数组类型 if(_.isArray(value)) return memo.concat( shallow ? value : _.flatten(value)); // 数据(value)已经处于底层, 不再是数组类型, 则将数据合并到memo中并返回 memo[memo.length] = value; return memo; }, []); };