【问题标题】:Flattening an array recursively (withoout looping) javascript递归地展平数组(不循环)javascript
【发布时间】:2015-12-06 21:30:29
【问题描述】:

我正在练习递归,并试图在不循环的情况下展平数组(仅限递归)。作为第一步,我采用了迭代方法,它奏效了,但我坚持使用纯递归版本:

function flattenRecursive(arr) {
    if (arr.length === 1) {
        return arr;
    }

    return Array.isArray(arr) ? arr = arr.concat(flattenRecursive(arr)) : flattenRecursive(arr.slice(1))
}

console.log(flattenRecursive([
    [2, 7],
    [8, 3],
    [1, 4], 7
])) //should return [2,7,8,3,1,4,7] but isn't - maximum call stack error


//working version (thanks @Dave!):

function flattenRecursive(arr) {
    if (arr.length === 1) {
        return arr;
    }

    return arr[0].concat(Array.isArray(arr) ? flattenRecursive(arr.slice(1)) : arr);
}

console.log(flattenRecursive([
    [2, 7],
    [8, 3],
    [1, 4], 7
]))

//returns [ 2, 7, 8, 3, 1, 4, 7 ]

【问题讨论】:

  • 提示:Array.isArray(arr) 永远为真
  • arr.concat(flattenRecursive(arr)) 导致无限递归。
  • @charlietfl - 第一次调用该函数时为真,然后使用相同的参数再次调用该函数 - arr - 因此将始终为真。它永远不会到达数组中的最后一项。
  • 只是好奇为什么要递归执行此操作。如果您不想就地执行它,那么执行它是微不足道的。这是一个思考练习吗?
  • @torazaburo 巩固我对递归的理解的练习(学术):) 你将如何做到这一点?

标签: javascript arrays recursion


【解决方案1】:

这是一个稍微不那么冗长的工作版本。

//using reduce
function flattenRecursive(arr) {
  return arr.reduce(function(result, a){
    return result.concat(Array.isArray(a) ? flattenRecursive(a) : a);
  }, []);
}

//without reduce
function flattenRecursive2(arr) {
  if (arr.length === 0)
    return arr;

  var head = arr.shift();
  if (Array.isArray(head))
    return flattenRecursive2(head).concat(flattenRecursive2(arr));
  else
    return [head].concat(flattenRecursive2(arr));
}

var testArray = [1,[2, 3],[[4, 5, [6, 7]], [8, 9]], 10];
console.log(flattenRecursive(testArray));
console.log(flattenRecursive2(testArray));
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

【讨论】:

  • 嘿@dave 太棒了,但内部 reduce 使用 each,这本质上是一个 for 循环。根据您提供的解决方案,我正在乱搞,有时 sh$t 就可以了!将我上面的代码更新为有效的解决方案,感谢您的启发!
  • @devdropper87 - 如果数组中的第一个元素不是数组,则递归函数将失败 - 例如console.log(flattenRecursive([7, [2, 7], [8, 3], [1, 4], 7 ]))
  • 我很难过,如果它不是数组,我会尝试做一个 else ,但这不起作用。你有什么建议? @dave 有什么建议吗?
  • @devdropper87 我添加了一个不使用.reduce()的替代方案@
  • @torazaburo 第二个示例现在已针对所有嵌套数组情况进行修复。
【解决方案2】:

对不起,我没有评论的声誉。这是我的 2 美分。

1) 注意你的初始状态。在这里,如果您的输入是̀arr = [[1,2]],您的函数似乎返回[[1,2]],而您希望它返回[1,2]

2) 在递归的核心中,您必须确保使用smaller argument. Here, you should concat the first element of your array with the flattened rest of the array. The functionslice` 递归调用您的函数可能会很方便。

3) 也可以使用类reduce 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-14
    • 2019-07-04
    • 2020-12-23
    • 2016-08-16
    • 2013-10-24
    • 2017-05-15
    • 2018-02-28
    • 2018-04-20
    相关资源
    最近更新 更多