是否有更简单的方法来交换数组中的两个元素?

var a = list[x], b = list[y];
list[y] = a;
list[x] = b;

您只需要一个临时变量。

var b = list[y];
list[y] = list[x];
list[x] = b;

10年后,随着ES6的大量采用,编辑劫持了最重要的答案:

给定数组arr =[1,2,3,4],你现在可以在一行中交换值,如下所示:

[arr[0], arr[1]] = [arr[1], arr[0]];

这将产生数组[2,1,3,4]。这是解构赋值。


好吧,你不需要缓冲两个值-只有一个:

var tmp = list[x];
list[x] = list[y];
list[y] = tmp;

对于数值,可以使用按位的异或来避免临时变量

list[x] = list[x] ^ list[y];
list[y] = list[y] ^ list[x];
list[x] = list[x] ^ list[y];

或算术和(注意,这仅适用于x + y小于数据类型的最大值时)

list[x] = list[x] + list[y];
list[y] = list[x] - list[y];
list[x] = list[x] - list[y];

这似乎还可以....

var b = list[y];
list[y] = list[x];
list[x] = b;

不管用

var b = list[y];

意味着变量b将在作用域的其余部分出现。这可能会导致内存泄漏。不太可能,但还是最好避免。

也许把这个放到array。prototype。swap中是个好主意

Array.prototype.swap = function (x,y) {
  var b = this[x];
  this[x] = this[y];
  this[y] = b;
  return this;
}

它可以被称为:

list.swap( x, y )

这是一种既避免内存泄漏又避免DRY的干净方法。


如果你想要一个单一的表达式,使用本地javascript, 记住,拼接操作的返回值 包含已删除的元素。

var A = [1, 2, 3, 4, 5, 6, 7, 8, 9], x= 0, y= 1;
A[x] = A.splice(y, 1, A[x])[0];
alert(A); // alerts "2,1,3,4,5,6,7,8,9"

编辑:

当array. splice()返回一个数组时,表达式末尾的[0]是必要的,在这种情况下,我们需要返回数组中的单个元素。


摘要:http://www.greywyvern.com/?post=265

var a = 5, b = 9;    
b = (a += b -= a) - b;    
alert([a, b]); // alerts "9, 5"

var a = [1,2,3,4,5], b=a.length;

for (var i=0; i<b; i++) {
    a.unshift(a.splice(1+i,1).shift());
}
a.shift();
//a = [5,4,3,2,1];

交换数组中两个连续的元素

array.splice(IndexToSwap,2,array[IndexToSwap+1],array[IndexToSwap]);

根据Metafilter上的某个人的说法, “最新版本的Javascript允许你更整洁地进行交换(以及其他事情):”

[ list[x], list[y] ] = [ list[y], list[x] ];

我的快速测试表明,这段python代码在JavaScript版本中运行良好 目前在“谷歌Apps Script”(“.gs”)中使用。 遗憾的是,进一步的测试表明这段代码给出了一个“Uncaught ReferenceError: Invalid left side in assignment.” 使用的JavaScript (".js")的任何版本 谷歌Chrome版本24.0.1312.57 m。


这是一个精简版 arr中i1和i2的值互换

arr.slice(0,i1).concat(arr[i2],arr.slice(i1+1,i2),arr[i1],arr.slice(i2+1))

你可以交换任意数量的对象或文字,甚至是不同类型的对象或文字,使用一个简单的恒等函数,如下所示:

var swap = function (x){return x};
b = swap(a, a=b);
c = swap(a, a=b, b=c);

针对你的问题:

var swap = function (x){return x};
list[y]  = swap(list[x], list[x]=list[y]);

这在JavaScript中是可行的,因为它接受额外的参数,即使它们没有声明或使用。赋值a=b等,发生在a被传递到函数之后。


有一种有趣的交换方式:

var a = 1;
var b = 2;
[a,b] = [b,a];

(ES6 way)


可以通过以下方式交换数组中的元素:

list[x] = [list[y],list[y]=list[x]][0]

示例如下:

list = [1,2,3,4,5]
list[1] = [list[3],list[3]=list[1]][0]
//list is now [1,4,3,2,5]

注意:它的工作方式与常规变量相同

var a=1,b=5;
a = [b,b=a][0]

下面是一个变体,它首先检查数组中是否存在索引:

Array.prototype.swapItems = function(a, b){
    if(  !(a in this) || !(b in this) )
        return this;
    this[a] = this.splice(b, 1, this[a])[0];
    return this;
}

如果索引不存在,它目前只会返回这个,但是您可以很容易地修改失败时的行为


Array.prototype.swap = function(a, b) {
  var temp = this[a];
  this[a] = this[b];
  this[b] = temp;
};

用法:

var myArray = [0,1,2,3,4...];
myArray.swap(4,1);

如果只需要交换第一个和最后一个元素:

array.unshift( array.pop() );

当这个问题被问到时,它并不存在,但是ES2015引入了数组解构,允许你这样写:

let a = 1, b = 2;
// a: 1, b: 2
[a, b] = [b, a];
// a: 2, b: 1

只是为了好玩,另一种不使用任何额外变量的方法是:

Var arr = [1,2,3,4,5,6,7,8,9]; //交换索引0和2 arr (arr)。长度]= arr[0];//将idx1复制到数组的末尾 Arr [0] = Arr [2];//复制idx2到idx1 Arr [2] = Arr [Arr .length-1];//复制idx1到idx2 arr.length——;//删除idx1(被添加到数组的末尾) Console.log (arr);// -> [3,2,1,4,5,6,7,8,9]


对于两个或多个元素(固定数量)

[list[y], list[x]] = [list[x], list[y]];

不需要临时变量!

我在考虑简单地调用list.reverse()。 但后来我意识到它只会作为交换列表。长度= x + y + 1。

对于可变数量的元素

我研究了各种现代Javascript结构,包括Map和Map,但遗憾的是,没有一个代码比这种老式的基于循环的结构更紧凑或更快:

function multiswap(arr,i0,i1) {/* argument immutable if string */ if (arr.split) return multiswap(arr.split(""), i0, i1).join(""); var diff = []; for (let i in i0) diff[i0[i]] = arr[i1[i]]; return Object.assign(arr,diff); } Example: var alphabet = "abcdefghijklmnopqrstuvwxyz"; var [x,y,z] = [14,6,15]; var output = document.getElementsByTagName("code"); output[0].innerHTML = alphabet; output[1].innerHTML = multiswap(alphabet, [0,25], [25,0]); output[2].innerHTML = multiswap(alphabet, [0,25,z,1,y,x], [25,0,x,y,z,3]); <table> <tr><td>Input:</td> <td><code></code></td></tr> <tr><td>Swap two elements:</td> <td><code></code></td></tr> <tr><td>Swap multiple elements:&nbsp;</td> <td><code></code></td></tr> </table>


下面是一个不会改变列表的一行代码:

let newList =对象。赋值([],列表,{[x]:列表[y], [y]:列表[x]})

(使用了2009年问题发布时还没有的语言功能!)


那么Destructuring_assignment呢

var arr = [1, 2, 3, 4]
[arr[index1], arr[index2]] = [arr[index2], arr[index1]]

还可以推广到

[src order elements] => [dest order elements]

为了简洁起见,这里有一个丑陋的一行代码版本,它只比上面所有的连接和切片稍微好看一点。公认的答案才是正确的选择,而且可读性更强。

考虑到:

var foo = [ 0, 1, 2, 3, 4, 5, 6 ];

如果你想交换两个下标(a和b)的值;这样就可以了:

foo.splice( a, 1, foo.splice(b,1,foo[a])[0] );

例如,如果你想交换3和5,你可以这样做:

foo.splice( 3, 1, foo.splice(5,1,foo[3])[0] );

or

foo.splice( 5, 1, foo.splice(3,1,foo[5])[0] );

两者都产生了相同的结果:

console.log( foo );
// => [ 0, 1, 2, 5, 4, 3, 6 ]

#splicehatersarepunks:)


如果你不想在ES5中使用临时变量,这是交换数组元素的一种方法。

var swapArrayElements = function (a, x, y) {
  if (a.length === 1) return a;
  a.splice(y, 1, a.splice(x, 1, a[y])[0]);
  return a;
};

swapArrayElements([1, 2, 3, 4, 5], 1, 3); //=> [ 1, 4, 3, 2, 5 ]

试试这个功能…

$(document).ready(function () { var pair = []; var destinationarray = ['AAA','BBB','CCC']; var cityItems = getCityList(destinationarray); for (var i = 0; i < cityItems.length; i++) { pair = []; var ending_point = ""; for (var j = 0; j < cityItems[i].length; j++) { pair.push(cityItems[i][j]); } alert(pair); console.log(pair) } }); function getCityList(inputArray) { var Util = function () { }; Util.getPermuts = function (array, start, output) { if (start >= array.length) { var arr = array.slice(0); output.push(arr); } else { var i; for (i = start; i < array.length; ++i) { Util.swap(array, start, i); Util.getPermuts(array, start + 1, output); Util.swap(array, start, i); } } } Util.getAllPossiblePermuts = function (array, output) { Util.getPermuts(array, 0, output); } Util.swap = function (array, from, to) { var tmp = array[from]; array[from] = array[to]; array[to] = tmp; } var output = []; Util.getAllPossiblePermuts(inputArray, output); return output; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


在没有临时变量或ES6交换方法的数组中交换第一个和最后一个元素[a, b] = [b, a]

[a.pop(),…a.slice(1), a.shift()]


考虑这样一个解决方案,不需要定义第三个变量:

函数swap(arr, from, to) { 加勒比海盗。拼接(from, 1, arr.)Splice (to, 1, arr[from])[0]); } Var字母= ["a", "b", "c", "d", "e", "f"]; 交换(字母,1,4); console.log(字母);// ["a", "e", "c", "d", "b", "f"]

注意:您可能希望添加额外的检查,例如数组长度检查。这个解决方案是可变的,所以交换函数不需要返回一个新的数组,它只是对传入的数组进行突变。


使用ES6可以这样做…

假设你有这两个数组……

const a = ["a", "b", "c", "d", "e"];
const b = [5, 4, 3, 2, 1];

你想交换第一个值:

const [a0] = a;
a[0] = b[0];
b[0] = a0;

和值:

a; //[5, "b", "c", "d", "e"]
b; //["a", 4, 3, 2, 1]

Var arr = [1,2]; 加勒比海盗。拼接(0,2,arr[1], arr[0]); console.log (arr);/ / (2, 1)


Typescript解决方案,克隆数组,而不是突变现有的

export function swapItemsInArray<T>(items: T[], indexA: number, indexB: number): T[] {
  const itemA = items[indexA];

  const clone = [...items];

  clone[indexA] = clone[indexB];
  clone[indexB] = itemA;

  return clone;
}

function moveElement(array, sourceIndex, destinationIndex) {
    return array.map(a => a.id === sourceIndex ? array.find(a => a.id === destinationIndex): a.id === destinationIndex ? array.find(a => a.id === sourceIndex) : a )
}
let arr = [
{id: "1",title: "abc1"},
{id: "2",title: "abc2"},
{id: "3",title: "abc3"},
{id: "4",title: "abc4"}];

moveElement(arr, "2","4");

Flow

不是就地解决方案

let swap= (arr,i,j)=> arr.map((e,k)=> k-i ? (k-j ? e : arr[i]) : arr[j]);

让swap= (arr,i,j)=> arr.map((e,k)=> k-i ?(k-j ?E: arr[i]): arr[j]); //测试指数:3<->5 (= 'f'<->'d') 设a= ["a","b","c","d","e","f","g"]; 设b= swap(a,3,5); console.log(“\ n”,b); console.log(示例流:,交换(a, 3, 5) .reverse () . join (' - '));

就地解决方案

Let swap= (arr,i,j)=> {Let t=arr[i];arr[我]= arr [j];加勒比海盗[j] = t;返回arr} //测试指数:3<->5 (= 'f'<->'d') 设a= ["a","b","c","d","e","f","g"]; Console.log (swap(a,3,5)) console.log(示例流:,交换(a, 3, 5) .reverse () . join (' - '));

在这个解决方案中,我们使用“流模式”,这意味着swap函数返回数组作为结果-这允许轻松地继续使用dot处理。(比如reverse和join在片段中)


就地交换

// array methods
function swapInArray(arr, i1, i2){
    let t = arr[i1];
    arr[i1] = arr[i2];
    arr[i2] = t;
}

function moveBefore(arr, el){
    let ind = arr.indexOf(el);
    if(ind !== -1 && ind !== 0){
        swapInArray(arr, ind, ind - 1);
    }
}

function moveAfter(arr, el){
    let ind = arr.indexOf(el);
    if(ind !== -1 && ind !== arr.length - 1){
        swapInArray(arr, ind + 1, ind);
    }
}

// dom methods
function swapInDom(parentNode, i1, i2){
    parentNode.insertBefore(parentNode.children[i1], parentNode.children[i2]);
}

function getDomIndex(el){
    for (let ii = 0; ii < el.parentNode.children.length; ii++){
        if(el.parentNode.children[ii] === el){
            return ii;
        }
    }
}

function moveForward(el){
    let ind = getDomIndex(el);
    if(ind !== -1 && ind !== 0){
        swapInDom(el.parentNode, ind, ind - 1);
    }
}

function moveBackward(el){
    let ind = getDomIndex(el);
    if(ind !== -1 && ind !== el.parentNode.children.length - 1){
        swapInDom(el.parentNode, ind + 1, ind);
    }
}

如果你因为某些原因不允许使用就地交换,这里有一个map的解决方案:

函数swapElements(数组,源,dest) { 返回源=== dest ? Array:阵列。Map ((item, index) => index === source ? 数组[dest]: index === dest ? 数组[来源]:item); } Const arr = ['a', 'b', 'c']; const s1 = swapElements(arr, 0,1); Console.log (s1[0] === 'b'); Console.log (s1[1] === 'a'); const s2 = swapElements(arr, 2,0); Console.log (s2[0] === 'c'); Console.log (s2[2] === 'a');

下面是快速复制粘贴的typescript代码:

function swapElements(array: Array<any>, source: number, dest: number) {
  return source === dest
    ? array : array.map((item, index) => index === source
      ? array[dest] : index === dest 
      ? array[source] : item);
}