展开一个数组

有时候,我们会遇到嵌套的数组:

[1, [2], [3, [[[4]]]]]

我们希望将他展开为这样, 称这种展开方式为 浅展开

[1, 2, 3, [[4]]]

也会希望展开到扁平,称这种展开方式为 深度展开

[1, 2, 3 ,4]

_.flatten

_.flatten(array, shallow):展开 array,通过 shallow 指明是 深度展开 还是 浅展开

源码

_.flatten = function (array, shallow) {
    return flatten(array, shallow, false);
};

用例

// 深度展开
_.flatten([1, [2], [3, [[4]]]]);
// => [1, 2, 3, 4];

// 浅展开
_.flatten([1, [2], [3, [[4]]]], true);
// => [1, 2, 3, [[4]]];

flatten

我们看到,_.flatten 的逻辑由内部函数 flatten 所完成,该内部函数被多个 API 所使用:

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) {
                // 如果不是深度展开
                // 只是从value(数组)中不断抽出元素赋值output中
                // 例如, value=[1,[3],[4,5]]
                // output = [....1,3,[4,5]....]
                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) {
            // 如果不是严格模式, 则value可以不是数组
            output[idx++] = value;
        }
    }
    return output;
};

flatten 接受四个参数:

  • input:待展开数组
  • shallow:是否是浅展开,反之为深度展开
  • strict:是否为严格模式
  • output:可以指定输出数组,如果指定了输出数组,则将展开后的数组添加至输出数组尾部

对传入数组 input 进行遍历,对于遍历到的元素 value

  • 如果 value 为数组,则需要展开,浅展开很简单,只是展开该元素最外一层数组,深度展开则需要递归调用 flatten
  • 如果 value 不为数组,则只有在非严格模式下该 value 才会被赋值到新的数组中。
// 指定了严格模式
flatten([1, [2], [3, [[[4]]]], {name: 'wxj'}], true, true)
// => [2, 3, [[4]]]

// 未指定严格模式
flatten([1, [2], [3, [[[4]]]], {name: 'wxj'}], true, false);
// => [1, 2, 3, [[4]], {name: 'wxj'}]

// 指定了输出数组
var output = [5, 6, 7];
flatten([1, [2], [3, [[[4]]]]], false, false, output);
// => output: [5, 6, 7, 1, 2, 3, 4]

results matching ""

    No results matching ""