在javascript中反转数组
Posted
技术标签:
【中文标题】在javascript中反转数组【英文标题】:reversing an array in javascript 【发布时间】:2017-09-15 03:25:56 【问题描述】:我有一个名为 reverseArray 的 javascript 函数,它接受一个数组作为参数,并以相反的顺序返回一个与输入数组具有相同值的新数组。我想创建一个名为 reverseArryInPlace 的函数,它将输入数组的值更改为相反的顺序。
function reverseArray(inputArray)
var outputArray = [];
for (var i = inputArray.length - 1; i >= 0; i--)
outputArray.push(inputArray[i]);
return outputArray;
function reverseArrayInPlace(inPlaceInputArray)
inPlaceInputArray = reverseArray(inPlaceInputArray);
console.log('Inside reverseArrayInPlace: ' + inPlaceInputArray);
return inPlaceInputArray;
var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log('Outside reverseArrayInPlace: ' + arrayValue);
// Expected Value: [5, 4, 3, 2, 1]
这是我执行这段代码时得到的结果:
Inside reverseArrayInPlace: 5,4,3,2,1
Outside reverseArrayInPlace: 1,2,3,4,5
在 reverseArrayInPlace 函数中,arrayValue 变量已按预期反转。为什么我在reverseArrayInPlace函数外引用同一个变量时,又回到原来的顺序了?
【问题讨论】:
如果有功课就好了;它具有一个好问题的所有品质 您认为“InPlace”部分发生在您的代码中的什么位置? 您的reverseArrayInPlace()
不会就地 反转,它会创建一个新数组(这不是就地)。要反转 就地 交换原始数组中的元素,请不要创建新元素。
可以使用Array.reverse()函数
这是 Eloquent Javascript 书中的一个问题,但它不是家庭作业,因为我不在学校
【参考方案1】:
这里的根本问题是原语在 JavaScript 中是按值传递的。有关详细信息,请参阅以下问题:
Javascript by reference vs. by value
作为一个简单的例子,下面是一个试图改变传递给它的字符串的函数:
var outsideValue = 'foo'
function mutate(value)
value = 'fish'
mutate(outsideValue);
console.log(outsideValue);
但是,控制台输出是foo
。
发生这种情况是因为mutate
函数中的value
变量是一个在最初调用该函数时引用了outsideValue
的变量。当它在函数体中被赋予新值时,它只是改变value
变量来引用一个新的字符串。因此,outsideValue
未受影响。
查看此答案以获取在适当位置反转的示例:
https://***.com/a/43486686/249933
注意,它不会重新分配函数参数。
【讨论】:
基元是按值传递的,value 没有对 outsideValue 值的引用,它有一个值的副本。如果该值是一个引用(对一个对象),那么是的,它们都将引用同一个对象。但在这种情况下,该值是一个引用,而不是一个原始值。 ;-) 所以现在我明白了,通过放弃数组参数,我实际上并没有改变全局变量。但在示例答案中,我们改为重新分配数组参数的各个索引。当我们这样做时,为什么全局变量会发生变化? @AGP,这就是对象引用和原始值之间的区别。基元不能更改,只有保存它们的变量可以被覆盖(使用新值)。每次我将它们分配给一个新变量时,它们都会作为副本传递。对象作为引用传递。在幕后,内存中的地址在哪里找到这个对象。如果我更改对象的某些属性,对象本身就会更改,因此知道该对象的每个人都“具有”这种更改。【参考方案2】:如果要原地反转,就必须原地反转。
function reverseArrayInPlace(array)
for (let i = 0, j = array.length - 1; i < j; i++, j--)
[array[i], array[j]] = [array[j], array[i]];
const a = [1,2,3,4,5];
reverseArrayInPlace(a);
console.log(a);
【讨论】:
好的,你能解释一下 [x,y]=[y,x] 语句中发生了什么吗?[a, b] = [b, a]
交换a
和b
的值,使用array destructuring assignment..
为什么当你重新分配数组的各个索引时全局变量(a)发生了变化,但是当我重新分配整个数组时,全局变量没有改变?【参考方案3】:
function reverseArray(inputArray)
var outputArray = [];
for (var i = inputArray.length - 1; i >= 0; i--)
outputArray.push(inputArray[i]);
return outputArray;
function reverseArrayInPlace(inPlaceInputArray)
inPlaceInputArray = reverseArray(inPlaceInputArray);
console.log('Inside reverseArrayInPlace: ' + inPlaceInputArray);
return inPlaceInputArray;
var arrayValue = [1, 2, 3, 4, 5];
**arrayValue = reverseArrayInPlace(arrayValue);**
alert('Outside reverseArrayInPlace: ' + arrayValue);
// Expected Value: [5, 4, 3, 2, 1]
//
您的代码是正确的,您只需替换一行并编写 arrayValue = reverseArrayInPlace(arrayValue); 代替 reverseArrayInPlace(arrayValue); 然后 arratValue 将打印期望值
【讨论】:
这不会原地反转。它将用 new 数组替换arrayValue
的值。
然后我们需要添加新变量并打印它而不是 arrayValue 像: var reversedValue = reverseArrayInPlace(arrayValue);然后打印这个新值 alert('Outside reverseArrayInPlace: ' + reversedValue);
你没有完全理解in place的意思。
这很清楚。 AGP 想要在 arrayValue 变量中打印反转数组,您可以在他的代码和他提出的问题中看到它。使用这一行“arrayValue = reverseArrayInPlace(arrayValue);”肯定会解决他的问题。请再读一遍问题,你就会明白了。
@NEO——这不是 OP 想要的。您正在创建一个新数组 (var outputArray = []
),然后将对它的引用分配给原始变量。原始数组对象仍然存在,没有改变,但现在可能已经准备好进行垃圾回收了。【参考方案4】:
正如其他人所说,数组是对象,因此它们是通过引用传递的。您必须修改原始数组,而不是创建新数组。
所以这是 reverseInPlace 的另一个版本,它使用 shift 从数组中删除最后一个元素,并使用 splice 将其插入新的地点:
function reverseInPlace(arr)
var i = arr.length;
while (i--)
arr.splice(i, 0, arr.shift());
var arr = [1,2,3,4,5];
console.log('Before: ' + arr.join());
reverseInPlace(arr);
console.log('After: ' + arr.join());
为了一些乐趣,您还可以利用 sort:
注意:这只适用于某些浏览器,它依赖于内置的排序算法,该算法依赖于实现。
function reverseInPlace(arr)
arr.sort(() => 1);
var arr = [47, 95, 80, 62, 8, 34, 31, 17, 62, 17, 85, 72, 51, 20, 68, 60, 30, 84, 7, 34];
console.log('Before: ' + arr.join());
reverseInPlace(arr);
console.log('After : ' + arr.join());
【讨论】:
很遗憾,您的“有趣”版本不起作用。它取决于内部排序算法和调用排序函数的顺序。要查看此内容,请尝试Array.from(length: 100, _ => Math.floor(Math.random() * 100)).sort(() => 1)
。
@torazaburo——它在 Firefox 38 中对我“有效”,(但在 IE 中失败)。 ;-) 我想知道这一点,很高兴确认我的怀疑是有根据的。
我认为这与浏览器根据数组的大小切换到不同的算法有关。以上是关于在javascript中反转数组的主要内容,如果未能解决你的问题,请参考以下文章