At some point in their career, developers need to swap values. Most of the time we use the one plain old solution of “using a temporary variable”. Ugh, if only there was a better way. But wait! There is, and there’s not just one but many. In desperate times, we scour the web for solutions, find one, and copy it without ever wondering how this little snippet of code works. Lucky for you, now is the time to learn about how to swap values easily and efficiently, putting an end to your misery.
Let’s just get the most obvious one out of the way.
function swapWithTemp(num1,num2){
console.log(num1,num2)
var temp = num1;
num1 = num2;
num2 = temp;
console.log(num1,num2)
}
swapWithTemp(2.34,3.45)
Yes, you are reading correctly. We can use some mathematics magic to swap your values.
function swapWithPlusMinus(num1,num2){
console.log(num1,num2)
num1 = num1+num2;
num2 = num1-num2;
num1 = num1-num2;
console.log(num1,num2)
}
swapWithPlusMinus(2.34,3.45)
Whaaat!? Yep, so let’s see how it’s working. We get the sum of both numbers on line 4. Now, if we subtract one number from the sum then we get the other number right. That’s what we are doing on line number 5. Subtracting num2 from the sum which is stored in num1 variable will give the original num1 value which we store in num2. And similarly, we get assign num2 value in num1 on line 6.
Beware: There is also a one line swap with + and — floating around on the internet.
Here’s how it looks:
function swapWithPlusMinusShort(num1,num2){
console.log(num1,num2)
num2 = num1+(num1=num2)-num2;
console.log(num1,num2)
}
swapWithPlusMinusShort(2,3)
The above program gives the expected result. The expression within ( )
stores num2 in num1 and then we subtract num1 — num2 which is nothing but subtracting num2 — num2 = 0. Hence, we get our result. But when we use floating-point numbers, we see some unexpected results.
Try playing with the values like below in your console.
function swapWithPlusMinusShort(num1,num2){
console.log(num1,num2)
num2 = num1+(num1=num2)-num2;
console.log(num1,num2)
}
swapWithPlusMinusShort(2,3.1)
We can achieve the same result just by using + operator as we did when using both + and -.
Let’s see it below:
function swapWithPlus(num1,num2){
console.log(num1,num2)
num2 = num1 + (num1=num2, 0)
console.log(num1,num2)
}
//Try with - operator
swapWithPlus(2.3,3.4)
The above program works but sacrifices readability. On line 4, in the ( ) we are assigning num1 to num2 and the 0 next to is the return value. In short, our line 4 looks like:
num2 = num1 + 0 => num2 = num1.
Hence, we get our result.
Note: Some JavaScript engines can perform their own optimizations to the above code that disregards + 0.
Let’s do some more magic with using * & / operators.
The principle is the same as the previous method but with some teeny tiny quirks.
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
swapWithMulDiv(2.34,3.45)
It’s the same as the previous one. We get the product of both the numbers
and store them in one of the numbers. That’s what we are doing on line number 5. Then we divide one of the numbers with the product to get the
first number and repeat the process to get the second number.
You did it! You are a “mathemagician”.
But wait a second! What about the quirk?
Well, let’s try this.
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//Try switching out the numbers and see what happens
swapWithMulDiv(2.34,0)
Our values are not swapped and we get a weird NaN instead. What’s that all about. If you remember your math classes, we were always told not to divide with 0 because it’s undefined. The reason lies in how limits work and some other reasons which we won’t get into. For now, let’s see other problems with this method
Consider this example:
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//Try switching the numbers and see what happens
swapWithMulDiv(2.34,Infinity)
Yep, it’s again NaN. Because you can’t divide anything with Infinity, it’s undefined.
Want to see one more. I thought so!
function swapWithMulDiv(num1,num2){
console.log(num1,num2)
num1 = num1*num2;
num2 = num1/num2;
num1 = num1/num2;
console.log(num1,num2)
}
//Try switching out the numbers and see what happens
swapWithMulDiv(2.34,-Infinity)
-Infinity would yield the same result as the previous example and the reason is the same as well.
As it turns out even a great “mathemagician” can’t do the impossible with all his powers.
Here’s a shorter version of swapping with * and / but with the same problems:
function swapWithMulDivShort(num1,num2){
console.log(num1,num2)
num2 = num1*(num1=num2)/num2;
console.log(num1,num2)
}
swapWithMulDivShort(2.3,3.4)
The above code is similar to the shorter code when we were swapping using + and -. We assign num2 to num1, then our line 4 looks something
like this:
num2 = num1 * num2 / num2=> num2 = num1
Voila! Our values are swapped.
function swapWithMul(num1,num2){
console.log(num1,num2)
num2 = num1 * (num1=num2, 1)
console.log(num1,num2)
}
//Try with / and ** operator
swapWithMul(2.3,3.4)
The above program works but sacrifices readability. In line 4, in the ( ) we are assigning num1 to num2 and the 1 next to is the return value. In short, our line 4 looks like:
num2 = num1 * 1 => num2 = num1
Hence, we get our result.
XOR manipulates the binary bits. It yields 1 when we have two different inputs and 0 otherwise.
So, let’s understand how it works!
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
// Try negative values
swapWithXOR(10,1)
4-bit binary of 10 -> 1010
4-bit binary of 1 -> 0001
Now,
On line 5: num1 = num1 ^ num2 => 1010 ^ 0001 => 1011 => 7 On line 6: num2 = num1 ^ num2 => 1011 ^ 0001 => 1010 => 10On line 7: num1 = num1 ^ num2 => 1011 ^ 1010 => 0001 => 1
Voila! And we have our swapped values.
Let’s see another example.
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
swapWithXOR(2.34,3.45)
Umm! Where are the swapped values? We just get the integer part of the
number. And that’s the problem right there. The XOR assumes that the input is an integer and hence performs the calculations accordingly. But the floating-point number are not integers and are represented by IEEE 754 standard, which breaks the numbers in three parts: a sign bit, a group of bits representing an exponent, and another group representing a number between 1 (inclusive) and 2 (exclusive), the mantissa. Hence we get incorrect values.
Another example:
function swapWithXOR(num1,num2){
console.log(num1,num2)
num1 = num1^num2;
num2 = num1^num2;
num1 = num1^num2;
console.log(num1,num2)
}
//Try experimenting with infinities and integer values.
swapWithXOR(-Infinity,Infinity)
Again. We don’t see the expected result. That’s because both Infinity and –Infinity are both floating-point numbers. And as we discussed above, floating-point numbers are a problem for XOR.
It manipulates the binary bits as well and is the opposite of XOR. XNOR
yields 0 when we have two different inputs and 1 otherwise. JavaScript doesn’t have a single operator that performs XNOR, so we use the NOT operator to negate the result of XOR.
So, let’s understand how it works!
function swapWithXNOR(num1,num2){
console.log(num1,num2)
num1 = ~(num1^num2);
num2 = ~(num1^num2);
num1 = ~(num1^num2);
console.log(num1,num2)
}
//Try negative values
swapWithXNOR(10,1)
4-bit binary of 10 -> 1010
4-bit binary of 1 -> 0001
On line 4:
num1 = ~(num1 ^ num2) => ~(1010 ^ 0001) =>~(1011) => ~11 => -12
Since we have a negative number, we need to convert it back to binary & perform 2’s complement to get back the decimal value like:
-12 => 1100 => 0011 + 1 => 0100
On line 5:
num2 = ~(num1 ^ num2) => ~(0100 ^ 0001) => ~(0101) => ~5 => -6
-6 => 0110 => 1001 + 1 => 1010 => 10
On line 6:
num1 = ~(num1 ^ num2) => ~(0100^ 1010) => ~(1110) => ~14 => -15
-15 => 1111 => 0000 + 1 => 0001 => 1
That took some time but we have our swapped values. But unfortunately, it’s plagued with the same problems as XOR. It can’t deal with floating-point numbers and infinities.
Try to experiment with some values like below
function swapWithXNOR(num1,num2){
console.log(num1,num2)
num1 = ~(num1^num2);
num2 = ~(num1^num2);
num1 = ~(num1^num2);
console.log(num1,num2)
}
swapWithXNOR(2.3,4.5)
It’s a one-line trick. Really! You only need a line to perform swapping and more importantly no math. You just need a basic knowledge of arrays. It may look weird but hold on tight.
So, let’s see it in action!
function swapWithArray(num1,num2){
console.log(num1,num2)
num2 = [num1, num1 = num2][0];
console.log(num1,num2)
}
swapWithArray(2.3,Infinity)
In the index 0 of the array we are storing num1, and in index 1 we are both assigning num2 to num1 and storing num2 as well. Also, we are just accessing [0] to store the num1 value from array in num2. And we can swap anything we want here integers, floating points including infinities as well as strings. It’s quite neat actually but we lose code clarity here. Let’s explore something else.
It is an ES6 feature. And it’s the simplest of them all. In a single line, we can swap values like:
let num1 = 23.45;
let num2 = 45.67;
console.log(num1,num2);
[num1,num2] = [num2,num1];
console.log(num1,num2);
Here’s a weird one. An IIFE is in short, a function that just executes immediately after it is defined.
Here’s how we can use it to swap values:
function swapWithIIFE(num1,num2){
console.log(num1,num2)
num1 = (function (num2){ return num2; })(num2, num2=num1)
console.log(num1,num2)
}
swapWithIIFE(2.3,3.4)
In the above example, we are immediately invoking a function on line 4. The parenthesis at the end are the arguments to the function. The second argument assigns num1 to num2 and the first argument, num1 is just returned. Hence, the values are swapped. Just keep in mind that this method of swapping is not efficient.
This article dove into a number of options you have for swapping values in
JavaScript. Hopefully, you find this information helpful, feel free to leave a comment with your thoughts. Thanks for reading!
Previously published at https://medium.com/@piyush.kochhar1/10-ways-to-swap-values-in-javascript-8a1d056352dd