在Javascript中交换整个数组

Swap entire arrays in Javascript

本文关键字:数组 交换 Javascript      更新时间:2023-10-28

当我试图制作一个函数来交换2个数组时,原始数组保持不变。

function swap(x, y) {
    var temp = x; x = y; y = temp;
}
u=[1, 0];
v=[0, 1];
swap(u, v);
console.log(u);
console.log(v);

这导致u为[1,0],v为[0,1]。函数调用交换后,这些值没有更改。

另一方面,如果我在没有函数调用的情况下执行此操作:

u=[1, 0];
v=[0, 1];
var temp = u;
u = v;
v = temp;
console.log(u);
console.log(v);

然后它们被正确地交换,u为[0,1],v为[1,0]。

我认为Javascript数组是通过引用传递的,而不是通过值传递的。我是不是误解了什么?

Javascript不能将引用传递给uv变量本身。因此,在swap()函数中,对xy的赋值不会改变对uv的赋值。Javascript传递对uv持有的对象的引用。因此,不能在swap()中更改uv变量。您可以更改它们所指向的对象的内容,从而可以修改uv所指向对象的属性。

由于我有C/C++背景,我认为Javascript在以"指针传递"的方式传递对象时会做什么。当您调用swap(u, v)时,传递给swap()函数的是一个指向u也指向的数组的指针。因此,现在有两个变量ux都"指向"同一个数组。因此,如果修改实际的数组,那么由于u指向同一个数组,两者都会看到修改。但是,在swap()函数中所做的任何操作都无法更改uv实际指向的对象


在Javascript中,改变原始变量指向的对象的唯一方法是使它们成为对象的属性,并像这样传递对象:

function swap(obj, x, y) {
    var temp = obj[x]; obj[x] = obj[y]; obj[y] = temp;
}
var container = {};
container.u = [1, 0];
container.v = [0, 1];
swap(container, "u", "v");
console.log(container.u);
console.log(container.v);

如果不介意从头开始重写两个数组,可以将一个数组的所有内容复制到临时数组,然后将一个阵列复制到另一个,然后将临时数组内容复制回第一个原始数组。这不是很有效,可能有更好的方法来解决你最初的问题,但它是可以做到的。

 function swap(x, y) {
      // remove all elements from x into a temporary array
      var temp = x.splice(0, x.length);
      // then copy y into x
      x.push.apply(x, y);
      // clear y, then copy temp into it
      y.length = 0;
      y.push.apply(y, temp);
 }

了解这些"参考/价值"问题的术语很难,但我会尽我所能。

对象/数组变量实际上只是引用。与C++不同,说"x=y"实际上并不会将对象的变量复制到新的内存位置。在内部,它只是复制一个指针位置。该语言没有在新实例中"自动重新创建"对象或数组之类的结构;如果出于某种原因,您想要维护一个数组的两个副本,则需要显式创建它,然后复制值(即= [];= new Array();= oldArray.map(...)等复制函数)

一个可能在概念上有所帮助的小代码示例。这些相同的规则适用于对象和数组。

a = {}; // In case you haven't seen it, this is like shorthand of "new Object();"
b = {};
c = b;
console.log(a === b); // false
console.log(b === c); // true
b.property = "hello";
console.log(c.property) // hello

就像Java一样,JavaScript是只传递值。给函数中的局部变量赋值永远不会对函数之外的任何东西产生任何影响。

它们是通过引用传递的,但它们也是通过引用分配的。当您编写x = y时,您并没有修改任何一个数组,只是让您的局部变量x引用与y相同的数组。

如果你想交换数组内容,你必须修改数组本身:

function swap(x,y) {
    var temp = x.slice(0);
    x.length = 0;
    [].push.apply( x, y );
    y.length = 0;
    [].push.apply( y, temp ); 
}

2022年2月交换2个完整数组内容的解决方案

您可以使用析构函数来交换两个数组:

let a = [  1,  2,  3, 4 ];
let b = ['a','b','c','d'];
[a,b] = [b,a];   // swap
console.log(a);  // ["a", "b", "c", "d"]
console.log(b);  // [1, 2, 3, 4, 5]

    let a = [  1,  2,  3, 4 ];
    let b = ['a','b','c','d'];
    
    [a,b] = [b,a];   // swap
    
    console.log(a);  // ["a", "b", "c", "d"]
    console.log(b);  // [1, 2, 3, 4, 5]

要交换2个阵列,可以使用

版本1

let arrA = [1,2,3,4];
let arrB = ['Eve', 'Bar', 'Foo'];
let tempArr = [arrA, arrB];  // constructing new array
arrA = tempArr [1];
arrB = tempArr [0];

版本1(人手不足)

let arrA = [1,2,3,4];
let arrB = ['Eve', 'Bar', 'Foo'];
    
// RHS : construction a new array 
// LHS : destruction of array
[arrB, arrA ] = [arrA, arrB];  

版本2(排列运算符)

let arrA = [1,2,3,4];
let arrB = ['Eve', 'Bar', 'Foo'];
let arrC = [...arrB]
arrB = [...arrA]
arrA = [...arrC]