关于这个问题还有其他问题,但我想知道为什么我的代码没有反转给定的数组。注意:我对编码非常陌生,只是教自己并试图为个人兴趣练习。
在书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的东西。
答案 0 :(得分:1)
虽然这不是最短的解决方案,但我试图将其编写为易于理解。
基本上我们在数组中左右创建2个索引指针,左边当然是从第一个元素开始,然后是右边的最后一个元素。
因为我们不需要交换中间部分,只需检查左边&lt;在一个while循环中,它会在它到达之前停止。
然后我们使用tmp var,在我们交换项目时用作临时占位符,之后我们可以增加左侧并减少右侧索引指针。
为了使其成为就地替换,我们使用索引数组访问方法,使用[]而不是切片等。
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;
答案 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)
但问题是如何使用其他 条件来扭转使用过的数组。
书中的提示几乎为您提供了解决方案。
关于
交换是
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;
}
}
编辑:按照评论中的建议,这里有这个函数的作用:它从提示实现方法:成对交换元素。第一个和最后一个,然后是第二个和第二个到最后一个,依此类推。