Javascript swap array elements

0 votes
asked May 16, 2009 by ken

Is there any simpler way to swap two elements in an array?

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

20 Answers

0 votes
answered Jan 16, 2009 by jakub-arnold

With numeric values you can avoid a temporary variable by using bitwise xor

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

or an arithmetic sum (noting that this only works if x + y is less than the maximum value for the data type)

list[x] = list[x] + list[y];
list[y] = list[x] - list[y];
list[x] = list[x] - list[y];
0 votes
answered May 16, 2009 by marc-gravell

Well, you don't need to buffer both values - only one:

var tmp = list[x];
list[x] = list[y];
list[y] = tmp;
0 votes
answered May 16, 2009 by tvanfosson

You only need one temporary variable.

var b = list[y];
list[y] = list[x];
list[x] = b;
0 votes
answered May 16, 2009 by stefan

This seems ok....

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

Howerver using

var b = list[y];

means a b variable is going to be to be present for the rest of the scope. This can potentially lead to a memory leak. Unlikely, but still better to avoid.

Maybe a good idea to put this into Array.prototype.swap

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

which can be called like:

list.swap( x, y )

This is a clean approach to both avoiding memory leaks and DRY.

0 votes
answered May 16, 2009 by kennebec

If you want a single expression, using native javascript, remember that the return value from a splice operation contains the element(s) that was removed.

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"

Edit:

The [0] is necessary at the end of the expression as Array.splice() returns an array, and in this situation we require the single element in the returned array.

0 votes
answered Jan 8, 2011 by r-way-orz

Digest from http://www.greywyvern.com/?post=265

var a = 5, b = 9;    
b = (a += b -= a) - b;    
alert([a, b]); // alerts "9, 5"
0 votes
answered Jan 17, 2011 by nathan-romano
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];
0 votes
answered Jan 9, 2012 by piyush-madan

To swap two consecutive elements of array

array.splice(IndexToSwap,2,array[IndexToSwap+1],array[IndexToSwap]);
0 votes
answered Jan 14, 2013 by david-cary

According to some random person on Metafilter, "Recent versions of Javascript allow you to do swaps (among other things) much more neatly:"

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

My quick tests showed that this Pythonic code works great in the version of JavaScript currently used in "Google Apps Script" (".gs"). Alas, further tests show this code gives a "Uncaught ReferenceError: Invalid left-hand side in assignment." in whatever version of JavaScript (".js") is used by Google Chrome Version 24.0.1312.57 m.

0 votes
answered Jan 16, 2013 by dansalmo

You can swap any number of objects or literals, even of different types, using a simple identity function like this:

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

For your problem:

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

This works in JavaScript because it accepts additional arguments even if they are not declared or used. The assignments a=b etc, happen after a is passed into the function.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...