reverseArrayInPlace()无法正常工作

时间:2016-11-07 21:43:50

标签: javascript arrays

关于这个问题还有其他问题,但我想知道为什么我的代码没有反转给定的数组。注意:我对编码非常陌生,只是教自己并试图为个人兴趣练习。

在书Eloquent Javascript中,我们被要求编写两个不同的函数来反转数组。第一个函数 reverseArray 应该输出一个与给定数据相反的新数组。那个很容易。

第二个函数 reverseArrayInPlace 应该改变给定的数组,使其反转。假设仅仅使用第一个函数然后将其值分配给第一个数组是“欺骗”#34;。另外,我们不能使用.reverse方法。

这是我的尝试,我无法弄清楚它为什么不起作用:

var reverseArrayInPlace = function(anArray) {
    for (var i = 1; i < anArray.length; i++) {
        anArray = anArray.slice(i, i+1).concat
        (anArray.slice(0,i)).concat(anArray.slice(i+1));
    }
}

注意:我不喜欢我写这个函数的方式,但是我无法确定它为什么不起作用。

这是本书中给出的测试代码和目标输出:

var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [5, 4, 3, 2, 1]

书中给出的暗示说:

&#34; 诀窍是交换第一个和最后一个元素,然后是第二个和倒数第二个元素,依此类推。您可以通过循环数组长度的一半来完成此操作(使用Math.floor向下舍入 - 您不需要触摸具有奇数长度的数组中的中间元素)并将元素交换到位置i处的元素在位置array.length - 1 - i。您可以使用局部变量暂时保留其中一个元素,用其镜像覆盖该元素,然后将局部变量中的值放在镜像过去的位置。&# 34;

我不喜欢我的想法,但我更喜欢这个暗示。是否有更多的东西更改阵列&#34;到位&#34;有暗示的想法比我的想法?

感谢您的帮助。而且,我们不能在给定的数组上使用名为.reverse的东西。

4 个答案:

答案 0 :(得分:1)

虽然这不是最短的解决方案,但我试图将其编写为易于理解。

基本上我们在数组中左右创建2个索引指针,左边当然是从第一个元素开始,然后是右边的最后一个元素。

因为我们不需要交换中间部分,只需检查左边&lt;在一个while循环中,它会在它到达之前停止。

然后我们使用tmp var,在我们交换项目时用作临时占位符,之后我们可以增加左侧并减少右侧索引指针。

为了使其成为就地替换,我们使用索引数组访问方法,使用[]而不是切片等。

&#13;
&#13;
var reverseArrayInPlace = function(anArray) {
  var left = 0, right = anArray.length - 1, tmp;
  while (left < right) {
    tmp = anArray[left];
    anArray[left] = anArray[right];
    anArray[right] = tmp;    
    left ++;
    right --;
  }
}

var a = [1,2,3,4,5];

reverseArrayInPlace(a);

console.log(a);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我看到两个错误:

首先,你加倍concat来电:

var reverseArrayInPlace = function(anArray) {
   for (var i = 1; i < anArray.length; i++) {
      anArray = anArray.slice(i, i+1).concat // two concats! one here and one on next line
      concat(anArray.slice(0,i)).concat
      (anArray.slice(i+1));
   }
}

另一个错误是你没有退货。修正后的功能如下:

var reverseArrayInPlace = function(anArray) {
   for (var i = 1; i < anArray.length; i++)
      anArray =
         anArray
         .slice(i, i + 1)
         .concat(anArray.slice(0, i))
         .concat(anArray.slice(i + 1));

   return anArray;
};

但是请注意,这甚至不是一个&#34;到位&#34;逆转。在获得最终结果之前,此代码将生成大量中间数组。一个真实到位的逆转会有很大的不同,可能是在交换元素。

根据要求,一种可能性是将元素从头开始交换元素,从中间停止。交换通常包括使用临时变量,这可被视为违反&#34;就地&#34;同样。

要完全就位,即使没有临时变量,也可以使用XOR技巧来交换元素。但这只适用于数字,而不是对象之类的东西。你也不想以这种方式交换中心元素(如果有的话),因为你会把它归零。

// tricky way to swap two elements (assumes front != back)
anArray[front] ^= anArray[back];
anArray[back]  ^= anArray[front];
anArray[front] ^= anArray[back];

答案 2 :(得分:0)

当您走到数组Indexes used: none 的末尾并返回新数组时,您的代码正常工作。

(array.length + 1)

但问题是如何使用其他 条件来扭转使用过的数组。

书中的提示几乎为您提供了解决方案。

关于

  • 交换
  • 数组长度的一半
  • array.length - 1 - i

交换

var numbers = [1, 2, 3, 4, 5, 6];

var reverseArrayInPlace = function(arr) {
  for (var i = 1; i < arr.length + 1; i++) {
    arr = arr.slice(i, i + 1).concat(arr.slice(0, i)).concat(arr.slice(i + 1));
  }
  return arr;
}

var r = reverseArrayInPlace(numbers);
console.log(r);

数组长度的一半

var n = [4, 9];
var temp = n[0]; // Assign left to a temporary (locale) variable for a "briefly hold"
n[0] = n[1]; // Assign right to left
n[1] = temp; // Assign the temporary variable (left) to right
console.log(n);

var half = Math.floor(arr.length / 2); 。它还可以捕获一个奇数长度

的数组
Math.floor

总计

Math.floor(7 / 2) -> 3

答案 3 :(得分:-2)

这是作者正在寻找的代码:

var reverseArrayInPlace = function(anArray) {
  for (var i = 0; i <= anArray.length / 2; i++) {
    var t = anArray[i];
    anArray[i] = anArray[anArray.length - 1 - i];
    anArray[anArray.length - 1 - i] = t;
  }
}

编辑:按照评论中的建议,这里有这个函数的作用:它从提示实现方法:成对交换元素。第一个和最后一个,然后是第二个和第二个到最后一个,依此类推。