使用rest参数将参数展平为一维数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用rest参数将参数展平为一维数组相关的知识,希望对你有一定的参考价值。

在尝试将多维数组展平为一维数组时,我开发了以下代码(http://codepen.io/PiotrBerebecki/pen/KrkdPj)。

例如,

flattenArray([1, [2, 3], 4, [5, [6]], 7])
// should return [1, 2, 3, 4, 5, 6, 7]


// Flatten an array
function flattenArray(input) {
  return input.reduce(function(prev, curr) {
    if (Array.isArray(curr)) {return prev.concat(flattenArray(curr));}
    else {return prev.concat(curr);}
  }, []);
}

console.log(  flattenArray([1, [2, 3], 4, [5, [6]], 7])  );
// [1, 2, 3, 4, 5, 6, 7]

以上似乎工作正常。

现在,我被要求创建另一个函数,而不是数组将为数字和数组的混合实现相同的结果。

例如,

flattenMix(1, [2, 3], 4, [5, [6]], 7);
// should return [1, 2, 3, 4, 5, 6, 7]

我通过添加rest参数稍微修改了上面的内容,以便函数可以接受任意数量的参数。但是我得到了maximum call stack错误。你知道下面的功能有什么问题吗?

// Flatten arguments (arbitrary length) consisting of a mix of numbers and arrays
function flattenMix(...input) {
  return input.reduce(function(prev, curr) {
    if (Array.isArray(curr)) {return prev.concat(flattenMix(curr));}
    else {return prev.concat(curr);}
  }, []);
}

console.log(  flattenMix(1, [2, 3], 4, [5, [6]], 7)  ); // should return [1, 2, 3, 4, 5, 6, 7]

更新1

下面的答案和建议表明我应该在递归调用...中使用flattenMix(...curr)扩展运算符。这样,当curr是一个数组(如测试的那样)时,curr的包含元素将被传递到flattenMix函数(而不是curr数组)。

答案

好吧,你可以使用扩展运算符。

function flattenMix(...input) {
    return input.reduce(function (prev, curr) {
        if (Array.isArray(curr)) {
            return prev.concat(flattenMix(...curr));
            //                            ^^^^^^^
        } else {
            return prev.concat(curr);
        }
    }, []);
}

console.log(flattenMix(1, [2, 3], 4, [5, [6]], 7));
另一答案

好吧,很容易。你的第一个方法已经可以处理一个数组,因为arguments基本上是一个数组,我们可以添加一个额外的行。

// Flatten an array
function flattenArray(input) {
  return input.reduce(function(prev, curr) {
    if (Array.isArray(curr)) {
      return prev.concat(flattenArray(curr));
    } else {
      return prev.concat(curr);
    }
  }, []);
}

function flattenMix() {
  return flattenArray([].slice.call(arguments));
}

console.log(flattenMix(1, [2, 3], 4, [5, [6]], 7));
另一答案

您的问题是您在递归而不是数组项中发送数组作为第一个参数。你可以使用flatten.apply(null, arr)flatten(...arr)

// Flatten arguments (arbitrary length) consisting of a mix of numbers and arrays

function flatten(...input) {
  return input.reduce(function(prev, curr) {
    return prev.concat(
      Array.isArray(curr) ? flatten(...curr) : curr
    );
  }, []);
}

console.log(flatten(1, [2, 3], 4, [5, [6]], 7)); // should return [1, 2, 3, 4, 5, 6, 7]
另一答案

有一个新方法Array.flat()

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

以上是关于使用rest参数将参数展平为一维数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在一维数组中“展平”或“索引”3维数组?

在 PHP 中将多维关联数组展平为一维引用数组

rest 参数与扩展运算符

Swagger-ui 将查询参数中的对象展平,但生成的角度客户端不会

Python计算两个numpy数组的交集(Intersection)实战:两个输入数组的交集并排序获取交集元素及其索引如果输入数组不是一维的,它们将被展平(flatten),然后计算交集

如何正确连接两个一维数组而不展平?