swap in-place

在javascript语言中,数组中的两个元素位置交换有以下几种方式:

Memo swap

使用临时变量存储其中一个元素的值,再进行交换,这应该是最常用的方式了。

1
2
3
4
5
6
7
8
9
function memoSwap(arr, iA, iB) {
  const tmp = arr[iA];
  arr[iA] = arr[iB];
  arr[iB] = tmp;
  return arr; 
}

// memoSwap([1,2,5,4,3], 2, 4)
// -> [1,2,3,4,5]

Bitwise swap(仅支持整数)

使用按位操作符(XOR)进行交换。

1
2
3
4
5
6
7
8
9
function bitwiseSwap(arr, iA, iB) {
  arr[iA] ^= arr[iB];
  arr[iB] ^= arr[iA];
  arr[iA] ^= arr[iB];
  return arr; 
}

// bitwiseSwap([1,2,5,4,3], 2, 4)
// -> [1,2,3,4,5]

不使用临时变量

使用临时变量看起来很简单,但有时我们不想创建多余的变量。

1
2
3
4
5
6
7
function swapInPlaceWithoutMemo(arr, iA, iB){
  arr[iB] = arr[iA] + (arr[iA] = arr[iB]) - arr[iB];
  return arr;
}

// swapInPlaceWithoutMemo([1,2,5,4,3], 2, 4)
// -> [1,2,3,4,5]

要想知道 swapInPlaceWithoutMemo() 是如何工作的,最关键是要清楚 (arr[iA] = arr[iB]) 做了哪些事情。

使用Splice

使用splice方法,也可以不使用临时变量。

1
2
3
4
5
6
7
function swapSpliceInPlaceWithotMemo(arr, iA, iB){
  arr[iA] = arr.splice(iB, 1, arr[iA])[0];
  return arr;
}

// swapSpliceInPlaceWithotMemo([1,2,5,4,3], 2, 4)
// -> [1,2,3,4,5]

解构赋值

ES6中新增一个特性叫“解构赋值”。

1
2
3
4
5
6
7
function destructuringSwap(arr, iA, iB){
  [arr[iA], arr[iB]] = [arr[iB], arr[iA]];
  return arr;
}

// destructuringSwap([1,2,5,4,3], 2, 4)
// -> [1,2,3,4,5]

目前该方式仅能在ES6中使用