JavaScript函数reverseArrayInPlace - Eloquent JavaScript Ch4

时间:2014-12-25 12:04:01

标签: javascript arrays

任何人都可以告诉我在倒车阵列上这个功能出错了吗?这是 Eloquent JavaScript 一书中的练习。

我通过控制台检查了我的变量,循环似乎正在工作但最后数组索引似乎没有被覆盖,我不明白为什么!

我正在寻找的答案是:

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

"use strict";
var sampleArray = [1,3,5,7,9];

function reverseArrayInPlace (someArray) {
	var MiddleIndex = (Math.floor(someArray.length/2));
	for (var i = 0;  i <= MiddleIndex-1; i++) {
		var currentValue = someArray[i];
		var mirrorIndex = someArray[someArray.length -i -1];
		var temp = currentValue;
		currentValue = mirrorIndex;
		mirrorIndex = temp;
	}
		
	return someArray;
}

console.log(reverseArrayInPlace(sampleArray));

8 个答案:

答案 0 :(得分:2)

正如其他人已经注意到的那样,您忘记了一项任务,因为currentValue = mirrorIndex;只是更改 currentValue的值,而不是数组本身的元素。同样适用于temp。更一般:您不能将Array元素作为引用存储到变量中,就像那样Array元素。

它还使您的功能看起来过于复杂。这有两种选择。首先,通过存储一个值来完成交换,替换元素,并将存储的值分配给另一个元素。使用Array.splice(参见MDN),在一行中完成同样的操作。

Here is a test表示3个就地反向功能。

function reverseInPlace(arr) {
 var len = arr.length-1, mid = Math.floor(len/2), i = -1;
 while( i++ < mid ) {
   var swap = arr[len-i]; // save swapvalue
   arr[len-i] = arr[i];   // assign current value to swap position
   arr[i] = swap;         // assign swapvalue to current position
 }
}

// Swapping in one line (using splice)
function reverseInPlace2(arr) {
 var mid = Math.floor(arr.length/2), i = -1;
 while( i++ < mid ) { arr[i] = arr.splice(-(i+1), 1, arr[i])[0]; }
}

// demo
var log = Helpers.log2Screen;
var arr = [1,2,3,4];
reverseInPlace(arr);
log( 'Even length: `reverseInPlace(arr) -&gt; [', arr, ']`' );

arr = [1,2,3,4,5,6,7];
reverseInPlace(arr);
log( 'Odd length: `reverseInPlace(arr) -&gt; [', arr, ']`' );

arr = [1,2,3,4,5];
reverseInPlace2(arr);
log( 'Use `Array.splice: reverseInPlace2(arr4) -&gt; [', arr, ']`' );

// clarification of what happens in your code
log('\n<b>Clarification of what happens in your code</b>');

var myArr = [1,2,3,4,5];
var el2 = myArr[2];

log('Assigned: `MyArr: ', myArr, ', el2: ', el2, '`'); 
log( 'Storing: `var el2 = myArr[2];`' );
el2 = myArr[0];
log( 'Assigning: `el2 = myArr[0];`' );
log( '`myArray` did not change `MyArr: ', myArr, '`' ); 
log( 'But `el2` did: ', '`el2: ', el2, '`' );
<!-- some helpers -->
<script src="https://rawgit.com/KooiInc/Helpers/master/Helpers-min.js"></script>

答案 1 :(得分:1)

我们不是反转数组,而是创建一个以相反顺序检索元素的getter阴影数组:

function reverse_shadow(arr) {
    var o = [];
    o.length = arr.length;
    arr.forEach(function(elt, i) {
        Object.defineProperty(o, i, { 
            get: function() { return arr[arr.length - i - 1]; } 
        });
    });
    return o;
}

var arr = [1, 2, 3, 4];
var reversed = reverse_shadow(arr);

>> reversed.join(' ')
<< "4 3 2 1"

通过将以下代码添加到函数的中间,我们可以扩展它以在元素添加到基础数组时自动更新阴影,而无需再次调用reverse_shadow

Object.observe(arr, function(changes) {
    changes.forEach(function(change) {
        if (change.name === 'length') { o.length = arr.length; }
        else if (change.type === 'add') {
            Object.defineProperty(o, change.name, {
                get: function() { return arr[arr.length - change.name - 1]; }
            });
        }
    });
});

>> arr.push(5);
>> reversed.join(' ')
<< "5 4 3 2 1"

答案 2 :(得分:1)

嘿所以这是我的解决方案,我认为它运作得很好:

function reverseInPlace(array) {
    for (var i = 0; i<array.length; i+=2) {
        array.unshift(array[i]);
    }
    array.splice(Math.floor(array.length/2), array.length/2);
    return array;
}

答案 3 :(得分:0)

这个版本似乎只做了最低限度的工作。

// Swap the first element with the last,
// then the 2nd with the 2nd-to-last, etc.
// Quit when the indices meet or pass in the middle.

var reverseArrayInPlace = function(array) {
  for(var left =0, rite = array.length-1; left < rite; left++, rite--){
    var leftcopy = array[left];
    array[left] = array[rite];
    array[rite] = leftcopy;
  }
}

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

答案 4 :(得分:0)

这可能是一种可能的解决方案,但我不确定它是否反过来。由于我创建了一个存储值的映射,然后将它们以相反的顺序放在原始数组中。

function reverseArrayInPlace(array){
    var map = {};
  for(var i = 0; i < array.length; i++){
    map[i] = array[i];
  }

  for(var i = 0; i <= (array.length - 1); i++){
    array[i] = map[(array.length - 1) - i];
  }

  return array;
}

答案 5 :(得分:0)

ECMAScript 2017答案:(根据该书的最新版本)

const reverseArrayInPlace = (array) => {
    let result = [];
    for (let index = 0; index < array.length; index++)
        if (index in array)
            result[array.length - index - 1] = array[index];
    return result;
}

//let myArray = [0, 1, 2, 3, undefined, 4, 5];
//myArray[100] = 100;
//reverseArray(myArray);
// → 100, <93 empty slots>, 5, 4, undefined, 3, 2, 1, 0"

更新:也适用于非整数索引

const reverseArrayInPlace = (array) => {
    let result = [];
    for (const key of Object.keys(array)) {
        if (String(parseInt(key)) === key && parseInt(key) >= 0)
            result[array.length - key - 1] = array[key];
        else
            result[key] = array[key];
    }
    return result;
}

答案 6 :(得分:0)

这是我的解决方案:

function reverseArrayInPlace(arr){
  for(let i of [...arr]) {
    arr.unshift(i) 
    arr.pop()
 }
}

let arrayValue = [1, 2, 3, 4, 5];

reverseArrayInPlace(arrayValue);

console.log(arrayValue);

答案 7 :(得分:0)

这是我雄辩的JS(第3版)中的任务解决方案

let numArray = [1, 2, 3, 4, 5];
reverseArrayInPlace(numArray);

function reverseArrayInPlace(number) {
    let newArray = [];
    for (let numbers of number) {
        newArray.unshift(numbers);
    }
    console.log(newArray);
}

// -> [ 5, 4, 3, 2, 1 ]