How to swap two variables in JavaScript
Asked Answered
B

22

233

I have this two variables:

var a = 1,
    b = 2;

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

Bilbrey answered 24/4, 2013 at 20:35 Comment(1)
Swap (computer science)#Using a temporary variableDielectric
A
360

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>
Adrenaline answered 24/4, 2013 at 20:39 Comment(8)
+1. But the shortest version will be in ECMAScript 6: [a, b] = [b, a];.Katinka
@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.Meridith
@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.Adrenaline
@FrançoisWahl well, I would not have guessed that this solution was so much slower. See also: jsperf.com/swap-array-vs-variable/3Dielectric
@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.Adrenaline
@Adrenaline Read the Dijkstra quote in Ted Hopp's answer.Rempe
I've read the article and I don't disagree. The concept of swapping two variables is nothing new 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".Adrenaline
This makes the code unnecessarily hard to read therefore I would avoid using it.Sisterinlaw
B
295

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

let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);
Brogdon answered 18/9, 2014 at 10:58 Comment(8)
anyone knows the name of such kind of swap in es6?Ammoniate
@Ammoniate - I think it's called array matching, a form of destructuring assignment.Duumvir
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.Cunha
Thanks for the name. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…Griggs
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).Irena
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.Frissell
@MartinTournoij, were you able to figure out why this weird thing was happening?Barbican
@Barbican This is because without ; , javascript interpret the code as let a=5, b=6[a,b] = [b,a] . So the error message will be b is not define. You can see more explanation in this article: freecodecamp.org/news/…Lynea
D
135

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

Duumvir answered 24/4, 2013 at 20:37 Comment(6)
Xor will work with any data type. It's the subtraction trick that will only work with numbers.Illegitimate
@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.Duumvir
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.Brabble
@Brabble - 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".Duumvir
@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.Brabble
I really like the Dijkstra quote on this answer! :-)Char
I
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
Irena answered 11/12, 2013 at 23:4 Comment(8)
The temp var version is slightly faster, and more general and more readable as well. jsperf.com/swap-two-numbers-without-tmp-var/9Alchemize
What does this () syntax even mean? how does it yield 0?Lessee
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.Irena
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".Pythia
@Alchemize 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.Irena
@Alchemize In the meantime, this solution has become faster than the solution with the temporary variable on several platforms: 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.Irena
@ChrisGWGreen: a = b + (b=a, "")Corrianne
@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.)Irena
M
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
Mamiemamma answered 4/11, 2015 at 10:24 Comment(0)
G
21

You can now finally do:

let a = 5;
let b = 10;

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

console.log(a, b);
Grayish answered 5/4, 2017 at 7:34 Comment(0)
S
20

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

Sector answered 19/11, 2013 at 1:37 Comment(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.Irma
W
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

Whereto answered 24/4, 2013 at 20:38 Comment(10)
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.Coakley
-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.Dielectric
@Coakley good aspect. I assumed the TO uses only integer variables like in his post, but good comment!Whereto
@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)Iveyivie
@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.Dielectric
@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 :PCoakley
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!Whereto
@Coakley Bitwise operator is consistently (and by far) the fastest on my machine: jsperf.com/swap-array-vs-variable/2Iveyivie
@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 solutionDielectric
@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".Brabble
M
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


Meridith answered 24/4, 2013 at 20:38 Comment(0)
L
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/

Lower answered 24/4, 2013 at 20:40 Comment(9)
Same faults as @DmiN's answer.Dielectric
where you find faults? It is not honorableLower
@AbdennourToumi I think Kay is referring to the fact that your answer only works with integers.Adrenaline
@Adrenaline : 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.Lower
@AbdennourToumi To clarify, I was just explaining what I thought Kay meant. It has nothing to do with honor.Adrenaline
@AbdennourToumi dear sir, I did not intent to stain your honour. o_O You may as well flag my answer. Just hover on the line and press the flag symbol on the left.Dielectric
@Kay , I'm sorry . I no longer have the intention that you thinkLower
This conversation is bizarre. @AbdennourTOUMI - variables aren't the same as integers. You can have variables that point to objects, strings, functions, null, etc.Illegitimate
@RobertGrant : Alright! in addition, we have the question as following :"My question is how to swap them? Only this variables, not any objects."Lower
T
6

ES6 Destructuring:

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

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

Tetanize answered 13/2, 2018 at 7:34 Comment(0)
P
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.

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

Single line swapping

a = a^b^(b^=(a^b));
Shylashylock answered 24/1, 2014 at 12:18 Comment(0)
L
4

Till ES5, to swap two numbers, you have to create a temp variable and then swap it or multiply and divide. 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

Liam answered 31/12, 2019 at 12:4 Comment(0)
K
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.

Keats answered 14/3, 2022 at 4:49 Comment(0)
C
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/

Coquito answered 21/11, 2013 at 7:49 Comment(7)
No need to use the slow arguments, just do b = (function (x){ return x; })(a, a=b).Irena
@RubenVerborgh yes but with arguments we're not defining a third variable!Coquito
Technically, the arguments list would also be a variable.Irena
@RubenVerborgh yes , but without "manual" definition/assignationCoquito
Well, you assign a to arguments[0] by passing it as a parameter.Irena
@RubenVerborgh yes , but you don't creating the arguments and its assignation happens "behind the scenes"Coquito
I have trouble even counting this as a one-liner because any solution could just omit line breaks like this.Cupel
C
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/

Creolized answered 26/3, 2015 at 5:17 Comment(0)
D
3

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

Simplest form possible:

enter image description here

Disembowel answered 1/1, 2022 at 2:51 Comment(1)
You're not allowed to use the let keyword twice when re-assigning a variableNashom
C
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);
Cleland answered 13/1, 2015 at 10:35 Comment(0)
A
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'}
Allogamy answered 16/4, 2020 at 17:55 Comment(0)
G
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);
Glove answered 23/4, 2020 at 11:6 Comment(0)
C
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];
Checkup answered 13/2, 2018 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.