How to swap two variables in JavaScript - javascript

I have this two variables:
var a = 1,
b = 2;
My question is how to swap them? Only this variables, not any objects.

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>

ES6 (Firefox and Chrome already support it (Destructuring Assignment
Array Matching)):
let a = 5, b = 6;
[a, b] = [b, a];
console.log(`${a} ${b}`);

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

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

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

You can now finally do:
let a = 5;
let b = 10;
[a, b] = [b, a]; // ES6
console.log(a, b);

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

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

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

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/

ES6 Destructuring:
Using an array: [a, b] = [b, a]; // my favorite
Using an object: {a, b} = {a:b, b:a}; // not bad neither

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.

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/

Single line swapping
a = a^b^(b^=(a^b));

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/

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

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.

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'}

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

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

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

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];

Related

Javascript if else loop?

I'm sure there probably is, however I'm not sure what it's called so apologises if this is something super similar. I'm wondering if there's a faster way to code the following:
var b = "#ff0002";
var o = "#46c029";
var i = "#f2ec00";
var n = "#f64c98";
var g = "#52c6f3";
if(a==1){
return b;
}else if(a==2){
return o;
}else if(a==3){
return i;
}else if(a==4){
return n;
}else if(a==5){
return g;
}
Yeah, lookup array:
return [b, o, i, n, g][a - 1];
Not necessarily faster, but definetly shorter :)
If you have large number of strings to compare from use Object like this:
myObj = {1: '#ff0002', 2: '#46c029', 3: "#f2ec00", 4: "#f64c98", 5: "#52c6f3"}
console.log(myObj[3]);
If you are using ES6 you can use Map() like this:
const myMap = new Map([[1, '#ff0002'], [2, '#46c029'], [3, "#f2ec00"], [4, "#f64c98"], [5, "#52c6f3"]])
console.log(myMap.get(3)); // or any key

Swapping object variables in Javascript without using a 3rd variable

There is a well known method to swap 2 numeric variables without using a 3rd variable with simple arithmetic operations.
a = 3;
b = 5;
b += a;
a = b - a;
b -= a;
console.log(a); //5
console.log(b); //3
No mystery here. But I need to swap two variables that are objects and I have no idea how to tackle this.
The objects are very complex with properties of different data types and methods. Here is an example for simplification:
a = {
label: "xxxxxxx",
active: false,
doThatThang: function(val) {
//some code
}
};
I'm currently using a 3rd variable to perform the swap but the objects are really big and it's messing with the animation where the variables are swapping values.
Use ES6 array destructuring.
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a);
console.log(b);
Ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Try ES6 Array Destructing assignment.
DEMO
let a = {
label: "111111",
active: false,
doThatThang: function(val) {
//some code
}
};
let b = {
label: "222222",
active: false,
doThatThang: function(val) {
//some code
}
};
console.log("Before swap");
console.log(a);
console.log(b);
[a, b] = [b, a];
console.log("After swap");
console.log(a);
console.log(b);
var a=1,
b=2,
output=document.getElementById('output');
output.innerHTML="<p>Original: "+a+", "+b+"</p>";
b = [a, a = b][0];
output.innerHTML+="<p>Swapped: "+a+", "+b+"</p>";
<div id="output"></div>
Use a third variable when swapping objects. There is no simpler way to do it in ES5.
var first = {property: 'value'}
var second = {more: 'stuff'}
console.log('Before')
console.log(first)
console.log(second)
var temp = first
first = second
second = temp
console.log('After')
console.log(first)
console.log(second)
Let Say a = 3 and b=5.
Then
a = a+b (ie 8)
b= a-b (ie 8-5 = 3)
a= a-b (ie 8-3 = 5).
Now these are swapped without using 3rd variable.

swapping values of two variables, order of precedence?

var a = 1, b = 9;
a, b = b, a;
console.log(a,b)
1 9
Is possible that the assignments were carried out in left-to-right order? So, "a" would take the value of "b" and and "b" the value of "a".
Swapping values should be pretty simple:
var temp = b;
b = a;
a = temp;
EDIT: if it's all about integers, swapping can happen even without additional variable:
b = b - a;
a = a + b;
b = a - b;

How to list multiple variables into a single variable in JavaScript?

This is probably a really basic question, but either there is no answer on the web or I'm not using the correct terminology. I want to store two separate variables (A and B) into 1 master variable, so that master = A then B.
So if A = 3, B = 8, master would equal 38. Anyone know how to do this in JavaScript? I'm not a programmer but here is my attempt.
var A = 1;
var B = 5;
var master = A, B;
document.write(master);
You seem to be requesting string concatenation. If you want an array, use one of the other answers. Otherwise: var master = A.toString() + B.toString(); See this JSFiddle.
Use an array:
var A = 1,
B = 5;
var master = [A, B];
master[0]; // 1
master[1]; // 5
Both objects and arrays are OK, as has been suggested. I'll just throw in another suggestion - an encapsulation ;)
function Master(a, b) {
this.first = a;
this.second = b;
this.both = function() {
return a + '' + b;
}
}
And to use it
var a = 3;
var b = 8;
var m = new Master(a, b);
alert(m.first); // 3
alert(m.second); // 8
alert(m.both()); // 38 (mind the parentheses, this is a function call!)
I know you said you're new, so I probably shouldn't being throwing arrays on you. However, for the others...
If you plan to get more dynamic than a few variables, you might want to invest in arrays.Put them into an array, then loop through the array printing them out as a string into a variable.
var myArray = new Array();
myArray.push(3);
myArray.push(8);
var myString = "";
for(var a = 0; a < myArray.length; a++)
{
myString += myArray[a].toString();
}
let 1st_new = [ [ 123, 'jack', 'white', 'tehran' ];
let 2nd_new= [ 456, 'roz', 'black', 'theran' ] ];
let 1st_list.push("1");
let 2st_list.push("2");
console.log(1st_new);
console.log(2nd_new);
#or you could make vairables of thge lists and put it inside a "var master" and print that out.

Why does this work? Object references in Javascript

I've finally been curious enough to find out why javascript does its voodoo magic to learn why not all object references are created equal.
Given the example:
var a, b, c, d;
a = 100; b = a;
c = {}; d = c;
b = 10; d.e = 'f';
console.log(a, b); // outputs 100, 10
console.log(c, d); // outputs object => e = 'f', object => e = 'f'
If all variables in javascript are objects, then what makes the use case with c and d cast explicitly as an Object so different than defining a and b as Number? Or, why will c and d be linked to one another, and not a and b?
All variables in JavaScript are not objects. There are native types as well.
c and d are not linked to one another. They are pointing to the same object reference. If you were to reassign d to something else, it will not affect c.
var c = {};
var d = c;
d = { foo: "bar" };
c === d // false
However, if you were to modify the object being referenced by c or d, it will modify the same object since c and d are both referring to the same object as in your example.
It looks to me that the difference is with b, you're reassigning the variable to a new object/value, while with d, you're modifying the existing object.
The value of a that is assigned to b is a Number. The value assigned from c to d is a reference to an Object.
var a, b, c, d;
a = 100; // a has value 100, a number
b = a; // b has value 100, a number
c = {}; // c has value p, a reference to some object P
d = c; // d has value p, a reference to P
b = 10; // b has value 10, a number
d.e = 'f'; // P.e has value 'f', a string

Categories