224

I have this two variables:

var a = 1,
    b = 2;

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

Lukas
  • 7,384
  • 20
  • 72
  • 127
  • 8
    [Swap (computer science)#Using a temporary variable](http://en.wikipedia.org/wiki/Swap_%28computer_science%29#Using_a_temporary_variable) … – Kijewski Apr 24 '13 at 20:37

22 Answers22

354

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>
showdev
  • 28,454
  • 37
  • 55
  • 73
  • 340
    +1. But the shortest version will be in ECMAScript 6: `[a, b] = [b, a];`. – dfsq Apr 24 '13 at 20:42
  • 8
    @Kay: It also seems to be much slower using an array instead of a third variable: [http://jsperf.com/swap-array-vs-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. – Nope Apr 24 '13 at 21:02
  • 2
    @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. – showdev Apr 24 '13 at 21:08
  • 3
    @FrançoisWahl well, I would not have guessed that this solution was so much slower. See also: http://jsperf.com/swap-array-vs-variable/3 – Kijewski Apr 24 '13 at 21:11
  • @FrançoisWahl No offense taken - I'm glad you brought it up. Personally, I would probably use a temporary variable (just like your answer), simply because it would be the first solution that popped into my head and the performance issues would be negligible for my applications. – showdev Apr 24 '13 at 21:15
  • 4
    @showdev Read the Dijkstra quote in Ted Hopp's answer. – Brian McCutchon May 13 '16 at 03:37
  • 1
    I've read the article and I don't disagree. The concept of swapping two variables is [nothing new](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Swapping_variables) and there are plenty of other methods posted here, each useful in its own right. I don't see the harm in having some fun with it. Check out my new book, "The Dao and Humility of Punchcard Coding". – showdev May 13 '16 at 17:43
  • This makes the code unnecessarily hard to read therefore I would avoid using it. – zendka Dec 30 '19 at 09:05
277

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

let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);
Saksham
  • 9,037
  • 7
  • 45
  • 73
Pedro Justo
  • 3,969
  • 1
  • 17
  • 21
  • 3
    anyone knows the name of such kind of swap in es6? – derek Apr 10 '16 at 05:09
  • 8
    @derek - I think it's called [_array matching_](http://es6-features.org/#ArrayMatching), a form of [_destructuring assignment_](http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment). – Ted Hopp Apr 22 '16 at 14:31
  • 6
    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. – mkey Feb 15 '17 at 21:03
  • Thanks for the name. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment – Hritik Feb 21 '17 at 08:41
  • 16
    Since V8 version 6.8, swapping variables with array destructuring should be as fast as with a temporary variable (https://v8project.blogspot.com/2018/06/v8-release-68.html). – Ruben Verborgh Aug 21 '18 at 01:47
  • 2
    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. – Martin Tournoij Mar 25 '21 at 05:22
  • @MartinTournoij, were you able to figure out why this weird thing was happening? – Shalvin Jul 20 '22 at 21:53
133

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

codejockie
  • 9,020
  • 4
  • 40
  • 46
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Xor will work with any data type. It's the subtraction trick that will only work with numbers. – Rob Grant Jan 16 '15 at 13:57
  • 12
    @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](http://www.ecma-international.org/ecma-262/5.1/#sec-11.10)). 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`. – Ted Hopp Jan 16 '15 at 17:25
  • 1
    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 Sep 21 '16 at 00:48
  • 1
    @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". – Ted Hopp Sep 21 '16 at 00:55
  • @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. – Beejor Sep 27 '16 at 04:20
  • I really like the Dijkstra quote on this answer! :-) – simbro Nov 08 '18 at 10:31
60

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
Community
  • 1
  • 1
Ruben Verborgh
  • 3,545
  • 2
  • 31
  • 43
  • 5
    The temp var version is slightly faster, and more general and more readable as well. http://jsperf.com/swap-two-numbers-without-tmp-var/9 – Antimony Mar 12 '14 at 22:45
  • What does this () syntax even mean? how does it yield 0? – Pete Alvin Mar 26 '14 at 22:35
  • 8
    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`. – Ruben Verborgh Mar 27 '14 at 08:12
  • 6
    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". – Chris GW Green Apr 03 '14 at 09:56
  • @Antimony Of course it is. The solution with a temporary variable would even allow to switch things of totally different datatypes. The spirit of the question seemed more to explore different options that are not the textbook solution. – Ruben Verborgh May 04 '14 at 13:25
  • @Antimony In the meantime, this solution has become faster than the solution with the temporary variable on several platforms: http://jsperf.com/swap-two-numbers-without-tmp-var/9. I don't disagree on readability, but note that the original question is ill-posed: technically, `b=2,a=1` is also a solution. My solution here strives to be interesting, not optimal, even though it is the fastest now. – Ruben Verborgh Jun 23 '14 at 09:20
  • 3
    @ChrisGWGreen: `a = b + (b=a, "")` –  Sep 24 '14 at 21:41
  • @ChrisGWGreen Yes, as the solution states, this works for all numbers; not for other types. A solution for strings is possible, as squint shows, but this is then only for strings (not for numbers anymore). For other object types, no such solution exists. (And note in general that this is just a neat trick; nobody would want to use this in practice.) – Ruben Verborgh Sep 25 '14 at 07:53
21

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
Peter
  • 620
  • 6
  • 13
21

You can now finally do:

let a = 5;
let b = 10;

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

console.log(a, b);
mehulmpt
  • 15,861
  • 12
  • 48
  • 88
19

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).

bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 1
    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. – Johnny Wong Jun 15 '15 at 03:07
11

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

DmiN
  • 736
  • 1
  • 7
  • 21
  • 19
    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. – cHao Apr 24 '13 at 20:39
  • -1: nice as a joke but not a real thing for the last 30 years. At least you should tell that this solution corrupts any non-integer value. – Kijewski Apr 24 '13 at 20:40
  • @cHao good aspect. I assumed the TO uses only integer variables like in his post, but good comment! – DmiN Apr 24 '13 at 20:40
  • 1
    @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) – Ben Harold Apr 24 '13 at 20:43
  • @php_surgeon the context of my comment was this answer, not your comment (notice the timestamp). I really hope you do not use swapping by xor in production code. – Kijewski Apr 24 '13 at 20:44
  • 1
    @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 Apr 24 '13 at 20:45
  • Well my thought is still, that the TO is a beginner. For sure it's not good to teach bad ways to code. But we also had to use quite this feature in exams, because we weren't allowed to use temp. variables! – DmiN Apr 24 '13 at 20:46
  • 1
    @cHao Bitwise operator is consistently (and by far) the fastest on my machine: http://jsperf.com/swap-array-vs-variable/2 – Ben Harold Apr 24 '13 at 21:08
  • 3
    @php_surgeon I changed the fiddle a bit so that the compiler cannot mark the variables as dead. http://jsperf.com/swap-array-vs-variable/3. The temp var solution is now 1/4 faster than the xor swap solution – Kijewski Apr 24 '13 at 21:15
  • 1
    @Kay In situations where something is stable, well-commented, the fastest technique, and used in only one or two places, I don't see why it wouldn't be fine in production code. Bitwise ops in general are a difficult concept, so if the code already uses a bunch of them, the maintainers would need to be familiar with them anyway. For most cases, it's obviously overkill. I just think blanket statements aren't always helpful; everything has a place, even "goto" and "eval". – Beejor Sep 21 '16 at 01:00
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


Nope
  • 22,147
  • 7
  • 47
  • 72
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/

Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
6

ES6 Destructuring:

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

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

Flavien Volken
  • 19,196
  • 12
  • 100
  • 133
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.

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
Teemu Ikonen
  • 11,861
  • 4
  • 22
  • 35
4

Single line swapping

a = a^b^(b^=(a^b));
Martijn
  • 13,225
  • 3
  • 48
  • 58
Saruselvi
  • 49
  • 2
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/

Ivan Chernykh
  • 41,617
  • 13
  • 134
  • 146
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/

Thilak Raj
  • 880
  • 3
  • 10
  • 25
3

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.

rajkanani
  • 173
  • 3
  • 5
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);
Mohammed Javed
  • 866
  • 2
  • 9
  • 24
1

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

Know more about JavaScript ES6 destructuring

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'}
SwiftNinjaPro
  • 787
  • 8
  • 17
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);
ganesh phirke
  • 471
  • 1
  • 3
  • 12
1

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

Simplest form possible:

enter image description here

MRPMOHIBURRAHMAN
  • 587
  • 3
  • 14
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];
Enogwe Victor
  • 70
  • 1
  • 5