243

I have this two variables:

var a = 1,
    b = 2;

My question is how to swap them? Only this variables, not any objects.

1

22 Answers 22

368

Here's a one-liner to swap the values of two variables.
Given variables a and b:

b = [a, a = b][0];

Demonstration below:

var a=1,
    b=2,
    output=document.getElementById('output');

output.innerHTML="<p>Original: "+a+", "+b+"</p>";

// swap values for variables "a" and "b"
b = [a, a = b][0];

output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>

Sign up to request clarification or add additional context in comments.

7 Comments

+1. But the shortest version will be in ECMAScript 6: [a, b] = [b, a];.
@Kay: It also seems to be much slower using an array instead of a third variable: http://jsperf.com/swap-array-vs-variable I only tested this in Chrome though. I wasn't able to test ECMAScript 6 version yet as it currently gives a Invalid left-hand side in assignment error.
@FrançoisWahl Good point. I think most of the answers here will work and are fairly equivalent. I suppose it's a trade off between temporary variable use, amount of code, and speed.
@FrançoisWahl well, I would not have guessed that this solution was so much slower. See also: jsperf.com/swap-array-vs-variable/3
@showdev Read the Dijkstra quote in Ted Hopp's answer.
|
322

ES6 (Firefox and Chrome already support it (Destructuring Assignment Array Matching)):

let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);

8 Comments

anyone knows the name of such kind of swap in es6?
@derek - I think it's called array matching, a form of destructuring assignment.
This appears to be about 35 times slower than the third variable method on nodejs 7.4.0/win7 64. But it sure is neat.
Since V8 version 6.8, swapping variables with array destructuring should be as fast as with a temporary variable (v8project.blogspot.com/2018/06/v8-release-68.html).
There's a gotcha here if you omit the ; on the line before the [a, b] = [b, a]: JS will do Weird Stuff™, presumable as it's merged with the previous line as an array/object index or some such.
|
136

You can do this:

var a = 1,
    b = 2,
    tmp;
tmp = a;
a = b;
b = tmp;

For readability and maintainability, this can't be beat (at least in JavaScript). Anybody maintaining the code (including you six months from now) will know exactly what's going on.

Since these are integers, you can also use any number of clever tricks1 to swap without using a third variable. For instance you can use the bitwise xor operator:

let a = 1, b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
    
console.log('a is now:', a);
console.log('b is now:', b);

This is called the XOR swap algorithm. Its theory of operation is described in this Wikipedia article.

1"The competent programmer is fully aware of the limited size of his own skull. He therefore approaches his task with full humility, and avoids clever tricks like the plague." — Edsger W. Dijkstra

6 Comments

Xor will work with any data type. It's the subtraction trick that will only work with numbers.
@RobertGrant - The xor operator in JavaScript converts its operands to 32-bit integers (using the ToInt32 internal method—see Section 11.10 of the ECMAScript standard). It does not produce the correct results for non-integer numerical values. It also converts non-numeric values to 32-bit integers. If you start with a = "hi" and b = "there", you end up with a == 0 and b == 0.
This trick works with any data type, provided you don't mind an integer result; the values are auto-cast to int32s. This means it can work with numeric strings, Booleans (0/1), null (0), and empty arrays/objects (0). Though the original type isn't preserved, so affected Booleans wouldn't work with typeof a == 'boolean' or a === false, for example. Real numbers work, except they're floored toward zero versus rounded to the nearest integer.
@Beejor - In other words, it works with any data type, except it doesn't (unless they are integer values). In my book, "swap" means "end with each variable having the value that the other one had", not "convert to int32 and then swap".
@TedHopp Fair enough. I meant "works" in terms of the fact you can throw any data type at it, not as in it works as a good swap solution. I agree it's not very useful in general.
|
61

Don't use the code below. It is not the recommended way to swap the values of two variables (simply use a temporary variable for that). It just shows a JavaScript trick.

This solution uses no temporary variables, no arrays, only one addition, and it's fast. In fact, it is sometimes faster than a temporary variable on several platforms.
It works for all numbers, never overflows, and handles edge-cases such as Infinity and NaN.

a = b + (b=a, 0)

It works in two steps:

  • (b=a, 0) sets b to the old value of a and yields 0
  • a = b + 0 sets a to the old value of b

8 Comments

The temp var version is slightly faster, and more general and more readable as well. jsperf.com/swap-two-numbers-without-tmp-var/9
What does this () syntax even mean? how does it yield 0?
The operator in the parentheses is the comma operator ,, and it has been wrapped to set the precedence right. The comma operator evaluates both of its arguments (in this case b=a and 0) and returns the last (in this case 0). So here, it has the effect of setting the new b to the old value of a, while yielding 0.
Am I right in thinking this only works for numeric value? You can't use this with e.g. var a ="hello" b="world" as a="world0".
@ChrisGWGreen: a = b + (b=a, "")
|
24

You can now finally do:

let a = 5;
let b = 10;

[a, b] = [b, a]; // ES6

console.log(a, b);

Comments

22

Since ES6, you can also swap variables more elegantly:

var a = 1,
    b = 2;

[a, b] = [b, a];

console.log('a:', a, 'b:', b); // a: 2 b: 1

Comments

21

Here's a one-liner, assuming a and b exist already and have values needing to be swapped:

var c=a, a=b, b=c;

As @Kay mentioned, this actually performs better than the array way (almost 2x as fast).

1 Comment

Like my ideal answer, just I prefer not redeclaring variable a & b when swapping, and use explicit variable name "tmp". Like: var a, b, tmp; a = 1; b = 2; tmp=a, a=b, b=tmp; Personal taste.
12

You could use a temporary swap variable or XOR.

a = a ^ b
b = a ^ b
a = a ^ b

This is just a basic logical concept and works in every language that supports XOR operation.

edit: see the Comments. Forgot to tell that this works for sure only with integer. Assumed the integer variables from question's thread

10 Comments

Works for programming interviews and other general trivia cases. Note, though, this is a rather stupid way to swap values in real life. For one thing, in JS, it only works with integers.
@Kay What do you mean by "not a real thing for the last 30 years?" I use bitwise operators whenever it makes sense, which is actually quite often (toggling an unknown boolean, for example)
@php_surgeon: XOR swapping hasn't been useful for quite some time now. Memory hasn't been that scarce for decades, and modern CPUs actually do faster with a temporary than with the XOR stuff. (The register interdependencies make it rather hard to pipeline.) Add in the fact that it's not as readable, and :P
@cHao Bitwise operator is consistently (and by far) the fastest on my machine: jsperf.com/swap-array-vs-variable/2
@php_surgeon I changed the fiddle a bit so that the compiler cannot mark the variables as dead. jsperf.com/swap-array-vs-variable/3. The temp var solution is now 1/4 faster than the xor swap solution
|
10

Use a third variable like this:

var a = 1,
    b = 2,
    c = a;

a = b; // must be first or a and b end up being both 1
b = c;

DEMO - Using a third variable


Comments

9

As your question was precious "Only this variables, not any objects. ", the answer will be also precious:

var a = 1, b = 2

a=a+b;
b=a-b;
a=a-b;

it's a trick

And as Rodrigo Assis said, it "can be shorter "

 b=a+(a=b)-b;

Demo: http://jsfiddle.net/abdennour/2jJQ2/

9 Comments

Same faults as @DmiN's answer.
where you find faults? It is not honorable
@AbdennourToumi I think Kay is referring to the fact that your answer only works with integers.
@showdev : Please read again question :"Only this variables, not any objects"....my answer is precious as question. I ask you to flag the comment .I repeat : It is not honorable.
This conversation is bizarre. @AbdennourTOUMI - variables aren't the same as integers. You can have variables that point to objects, strings, functions, null, etc.
|
6

ES6 Destructuring:

Using an array: [a, b] = [b, a]; // my favorite

Using an object: {a, b} = {a:b, b:a}; // not bad neither

Comments

6

Till ES5, to swap two numbers, you have to create a temp variable and then swap it. But in ES6, its very easy to swap two numbers using array destructuring. See example.

let x,y;
[x,y]=[2,3];
console.log(x,y);      // return 2,3

[x,y]=[y,x];
console.log(x,y);      // return 3,2

Comments

4

How could we miss these classic oneliners

var a = 1, b = 2
a = ({a:b, _:(b=a)}).a;

And

var a = 1, b = 2
a = (_=b,b=a,_);

The last one exposes global variable '_' but that should not matter as typical javascript convention is to use it as 'dont care' variable.

5 Comments

There is a typo in the second one. It should be a = (_=b,b=a,_);
What does the underscore _ mean? Why does it not need declaration?
underscore is just global variable name, you can replace it with any valid one. e.g. a = (justsomething=b,b=a,justsomething)
Oh no, don't use undeclared magic-global vars! That's a sure way to horrible bugs in real life.
Anyone using underscore.js is going to be very unhappy if they try the second one.
4

Single line swapping

a = a^b^(b^=(a^b));

Comments

4

Although the same answer is given previously, but here is a png to describe it.

Simplest form possible:

enter image description here

1 Comment

You're not allowed to use the let keyword twice when re-assigning a variable
4

first way,

var a = 5, b = 9;

a = a - b;
b = a + b;
a = b - a;

console.log(a, b);

second way

var a = 19, b = 22;

[a, b] = [b, a];

console.log(a, b);

simple and clear answer.

Comments

3

I see kind of programming olympiad here. One more tricky one-line solution:

b = (function(){ a=b; return arguments[0]; })(a);

Fiddle: http://jsfiddle.net/cherniv/4q226/

7 Comments

No need to use the slow arguments, just do b = (function (x){ return x; })(a, a=b).
@RubenVerborgh yes but with arguments we're not defining a third variable!
Technically, the arguments list would also be a variable.
Well, you assign a to arguments[0] by passing it as a parameter.
@RubenVerborgh yes , but you don't creating the arguments and its assignation happens "behind the scenes"
|
3
var a = 5;
var b = 10;

b = [a, a = b][0];
//or
b = [a, a = b];
b = b[0];

//or
b = [a, b];
a = b[1];
b = b[0];


alert("a=" + a + ',' + "b=" + b);

remove or comment the 2 //or's and run with the one set of code

http://jsfiddle.net/USdv8/57/

Comments

2

We are able to swap var like this :

var val1 =  117,
    val2 = 327;

val2 = val1-val2; 
console.log(val2);
val1 = val1-val2;
console.log(val1);
val2 = val1+val2;
console.log(val2);

Comments

1

Because I hear this method runs slower:

b = [a, a = b][0];

If you plan on storing your vars in an object (or array), this function should work:

function swapVars(obj, var1, var2){
    let temp = obj[var1];
    obj[var1] = obj[var2];
    obj[var2] = temp;
}

Usage:

let test = {a: 'test 1', b: 'test 2'};

console.log(test); //output: {a: 'test 1', b: 'test 2'}

swapVars(test, 'a', 'b');

console.log(test); //output: {a: 'test 2', b: 'test 1'}

Comments

1

We can use the IIFE to swap two value without extra parameter

var a = 5, b =8;
b = (function(a){ 
    return a 
}(a, a=b));

document.write("a: " + a+ "  b:  "+ b);

Comments

0
let a = 2, b = 4;
[b, a] = [a, b];

a more verbose approach would be

let a = 2, b = 4;
a = [a, b];
b = a[0];
a = a[1];

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.