使用一个参数的JavaScript反转数组函数。

3

我在尝试编写一个函数的主体,该函数递归地反转数组,但只有一个参数。

function ReverseArray(arr) {

  var i = 0;
  var j = arr.length - 1;

  if (i < j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    return ReverseArray(arr);
  }

  return arr;
}   

我意识到这样做行不通,因为函数调用自身时变量会被重新初始化。
我现在只是在寻找一些想法,因为我陷入了困境。

http://stackoverflow.com/questions/5164039/javascript-recursion - The Alpha
1个参数限制来自哪里? - zerkms
@zerkms:我猜这是作业。没有其他理由能解释这么随意的限制。不知道是否可以通过使用arguments来作弊? - Matt Burland
@Matt Burland:我知道这是作业。只是我没想到它会那么愚蠢。 - zerkms
1
@zerkms:前段时间我在Meta上问了这个问题 - Matt Burland
显示剩余2条评论
8个回答

2
首先,对于那些可能正在寻找如何反转数组的人,如果不是为了作业而是真正的问题,请使用Array.reverse,不要浪费时间尝试自己实现。
如果你一定要这样做,那么这里的技巧就是在递归时传递一个较小的数组(通过slice减去第一个和最后一个元素),并在展开时使用concat重新构建最终的数组。例如:

function ReverseArray(arr) {
  if (arr.length < 2) {
    return arr;
  } else {
    var first = arr[0];
    var last = arr[arr.length - 1];
    return [last].concat(ReverseArray(arr.slice(1, length - 1))).concat([first]);
  }

}

alert(ReverseArray([1,2,3,4,5]));


1
只有一个参数会显得非常丑陋。而且看起来对于教育毫无用处。 (+1) - zerkms
1
顺便提一下,试试 ReverseArray([1]) - zerkms
@zerkms:发现得好。已修复。 - Matt Burland
1
你把它搞得太复杂了。否则的话,可以这样写:var first = arr.pop(); return [first].concat(ReverseArray(arr)); - Dave

1

有一个Array.reverse方法。

无论如何...为了测试/学习目的:

["a","b","c"].map(function(v,i,a) {return a[a.length-i-1]})

v代表值,i代表迭代次数,a代表数组。

第一次迭代:

v="a"; i=0; a=["a","b","c"];

第二次迭代:

v="b"; i=1; a=["a","b","c"];

第三次迭代:

v="c"; i=2; a=["a","b","c"];


0
为什么你想要编写自己的反转方法?为什么不直接使用数组上的反转方法呢?
function ReverseArray(arr) {
    arr = arr.reverse();
}

更新

由于您可以在任何需要的地方调用反转方法,因此上述方法显然不再有太多意义。


2
为什么还要包装它呢?显然,OP学习了一些FP(或类似的)实践。 - zerkms
OP正在要求一个递归解决方案。 - Bergi

0

我使用 shift、pop、unshift 和 push 来避免对数组进行部分复制。这可能比在每个递归调用上使用 slice 对数组的一部分进行复制略微快一些,但不要指望它能胜过非递归解决方案或内置的 reverse 方法:

function recReverse(list){
  if(list.length>=2){
    var lo=list.shift();
    var hi=list.pop();
    list=recReverse(list);
    list.unshift(hi);
    list.push(lo);
  }
  return list;
}

以及fiddle


0

我认为以下解决方案是最简单的递归实现:

var a = [1,2,3,4,5];
alert(ReverseArray(a));

function ReverseArray(arr) {
    if(arr.length < 2) {
        return arr;
    } else {
        return [arr.pop()].concat(ReverseArray(arr));
    }
}


-1

假设你有一个数组 [1 2 3 4 5]

简单地将最后一个数字存储在某个地方,并再次将1-4输入函数中(结果为5-1234)

当输入的数组中只有一个数字时,将该数字作为单个数组成员返回。

当数组被返回时,将返回的数组附加到临时数字中,形成一个新数组。

这应该是4-123,然后是3-12,然后是2-1,所有这些都会反馈回来,结果为5-4-3-2-1

简化版:

var input_array = [1,2,3,4,5]

function rev(input) {
  if (input.length == 1) { return input; }
  if (input.length == 0) { return []; }
  return [input[input.length-1]].concat(rev(input.splice(0, input.length-1)));
}

rev(input_array);

展开版本:

var input_array = [1,2,3,4,5]

function rev(input) {
  if (input.length == 1) { return input; }
  if (input.length == 0) { return []; }
  var last = [input[input.length-1]];
  var newarr = rev(input.splice(0, input.length-1));
  var answer = last.concat(newarr);
  return answer;
}

rev(input_array);

不,你不想返回一个数字,而是一个数组。此外,“当只有一个数字时”并不是基本情况。 - Bergi
是的,那就是我想说的。已经编辑过来反映了。返回它作为[1],而不是1。实际上,如果你检查返回值的类型,它仍然可以工作,但检查长度比检查类型更明智。 - philz
1
你的函数在空数组上仍然失败了。 - Bergi

-1
你需要做的是这个。
function reverse(x, i, j) {
    if (i < j) {//Swap
        var tmp = x[i];
        x[i] = x[j];
        x[j] = tmp;
        reverse(x, ++i, --j);//Recursive
    }
}

function reverseIt(x) {
    console.log(x);
    reverse(x, 0, x.length - 1);
    console.log(x);
}


var q = [1, 2, 3, 4, 5, 6, 7, 8, 9];
reverseIt(q);

然后尝试将临时值存储到本地存储中。 - Muneeb Zulfiqar
1
将tempvalues存储在本地存储中。--- 你完全没有抓住重点。 - zerkms

-1
function reverseArray(origArray)
{
    if (origArray.length > 1) {
        var element = origArray[0];
        var newArray = reverseArray(origArray.slice(1));
        newArray[newArray.length] = element;
        return newArray;
    } else {
        return origArray;
    } 
}

[] 实际上是一个有效的数组。 - zerkms
origArray.length == 1 的情况下,element 是从哪里来的?你到底需要这种情况吗? - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接