使用for循环反转数组

3
快速的JavaScript问题。在下面的代码片段中,我正在反转传递给函数reverseArray的数组arr
在第一段代码中,尽管在循环中我正在操作变量newArr,它保持了arr的初始值,但看起来本地变量arr仍在改变。因此,当arr.length达到值3时,循环失败。
function reverseArray (arr) {
    var newArr = [];
    var inArr = arr;
    console.log(inArr);
    for (i = 0; i < arr.length; i++) {      
        newArr[i] = inArr.pop(i);       
    }   
    return newArr;
}
reverseArray(["A", "B", "C", "D", "E", "F"]);

// OUTPUT: ["F", "D", "E"]

另一方面,如果我将 arr.length 存储在本地变量 numArr 中,那么它就能完美地反转该数组。
function reverseArray (arr) {
    var numArr = arr.length;    
    var newArr = [];    
    for (i = 0; i < numArr; i++) {      
        let inArr = arr;
        newArr[i] = inArr.pop(i);       
    }
    return newArr;
}

reverseArray(["A", "B", "C", "D", "E", "F"]);

// OUTPUT: ["F", "E", "D", "C", "B", "A"]

我错过了什么?


pop() 不需要任何参数。 - Ry-
为什么你有三个数组?数组的赋值操作会赋予对象引用。传递的数组也会被改变。 - Nina Scholz
@Ry- 你是对的,但在这种情况下,那并没有什么区别。 - leonardofed
9个回答

3

pop (MDN, 规范) 是一个修改方法:它改变被调用的数组的状态。所以自然而然地,inArr.pop(1) 修改了 arr(在你的第一个示例中),因为 inArrarr 都指向同一个数组。

值得注意的是,pop 不接受任何参数,因此 1 并没有起到什么作用。

在你的第一个示例中,最好的方法是将初始值 arr.length - 1 赋给另一个变量(比如说 j),然后使用 arr[j] 获取值,并在增加 i 的同时减小 j。(此外,inArr 没有意义,你需要声明 i 来避免我所谓的隐式全局变量的恐怖

function reverseArray (arr) {
    var newArr = [];
    for (var i = 0, j = arr.length - 1; i < arr.length; i++, j--) {      
        newArr[i] = arr[j];
    }   
    return newArr;
}
console.log(reverseArray(["A", "B", "C", "D", "E", "F"]));

您也可以直接使用arr[arr.length - i - 1],而不是使用第二个变量:

function reverseArray (arr) {
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {      
        newArr[i] = arr[arr.length - i - 1];
    }   
    return newArr;
}
console.log(reverseArray(["A", "B", "C", "D", "E", "F"]));


有道理,但是为什么当我将numArr = arr.length赋值给第二个片段时,numArr不会随着arr的减少而改变呢? - leonardofed
@leonardofed - 因为 numArrarr 没有任何联系。numArr = arr.length 复制length的值到numArr中,之后就没有继续的关联了。 - T.J. Crowder
第二种解决方案对于数字并不适用。例如:[0,1,2,3,4,5]。 - Venu Madhav
@VenuMadhav - 第二种解决方案确实适用于该数组(或任何其他数组):https://jsfiddle.net/tjcrowder/nu4pxLkr/ - T.J. Crowder

3
你可以复制数组,并使用复制的长度来检查下一个弹出/推入命令。

function reverseArray(array) {
    var newArr = [],
        inArr = array.slice();    // take copy of primitive values

    while (inArr.length) {        // check decrementing length
        newArr.push(inArr.pop());
    }
    return newArr;
}

console.log(reverseArray(["A", "B", "C", "D", "E", "F"]));

为了满足条件,您也可以使用一个 for 语句。

function reverseArray(array) {
    var newArr = [],
        inArr = array.slice();    // take copy of primitive values

    for(; inArr.length; ) {       // check decrementing length
        newArr.push(inArr.pop());
    }
    return newArr;
}

console.log(reverseArray(["A", "B", "C", "D", "E", "F"]));


在适合使用while的情况下,使用for有什么作用? - T.J. Crowder

1
function reverseArray(a) {
    let arrayLength = a.length
    for (let i = 0; i< arrayLength/2; i ++){
      let temp =  a[i]
    a[i] = a[arrayLength -(i+1)]
    a[arrayLength - (i+1)] = temp
}
return a
}
reverseArray([1,2,3,4,5,6,7,8,9]) //expect: 9,8,7,6,5,4,3,2,1

实际上,我们可以让 i < Math.floor(arrayLength) 以消除中间元素。这种情况是为了不改变其自身的位置。 - Mikel

1

例子:

fruit=['banana', 'orange', 'mango', 'lemon'] //array
    
z=[] //empty array

for(i=(fruit.length-1);i>-1;i--){    
  z.push(fruit[i])
}

//i>-1 because the index of array ends at 0
    
console.log(z)


1

以下是使用两个For循环的示例:

let arr = [1, 12, 15, 16, 78, 89, 53];
for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    let c, a, b;
    b = arr[i];
    arr[i] = arr[j];
    arr[j] = b;
  }
}
console.log(arr);


just ignore variables c and a - Aditya Bhadoria

0
你的第一个函数存在问题,当你从数组 arrpop 一个元素时,实际上是在减少数组 arr 的长度。这就是为什么你看到的结果比原始元素数量少的原因。
所以你的代码像这样工作:
1st pass: i=0 and arr.length = 6; // 0<6 true
2nd pass: i=1 and arr.length = 5; // 1<5 true
3rd pass: i=2 and arr.length = 4; // 2<4 true
4th pass: i=3 and arr.length = 3; // 3<3 false and it does not execute

所以你只看到了三个结果。


OP可以这样做,但在构建反向数组时修改源数组(或其副本)是没有意义的。 - T.J. Crowder
@T.J.Crowder,我已经更新了我的答案。感谢您指出。 - Inus Saha

0
你可以尝试使用这段代码:
function reverseString(str) {
    var newString = "";
    for (var i = str.length - 1; i >= 0; i--) {
       newString += str[i];
    }

    return newString;
}

0
let input = ["A", "B", "C", "D", "E", "F"];
let output = [];

for(let i = 1; i <= input.length; i++) {

    // determine correct array index in respect to the current iteration
    let index = input.length - i;

    // push to new array
    output.push(reverse[index]);
}

// verify result
console.log(output);

1
虽然这段代码可能提供了问题的解决方案,但最好添加上为什么/如何运作的上下文。这可以帮助未来的用户学习并最终将该知识应用到他们自己的代码中。当代码被解释时,您还可能会得到用户的积极反馈/赞同。 - Amit Verma

0

这是一个类似的代码,用于反转数组。

function reverseArray(arr) {
    let newArr = [];
    for (i = arr.length - 1; i >= 0; i--) {
        newArr.push(arr[i]);
    }
    return newArr;
}
console.log(reverseArray(["A", "B", "C", "D", "E", "F"]));
//output: ["F","E","D","C","B","A"]

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