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.
Related
I was wondering if there is any way to simplify this if/else statement, just curious about finding an inline way of solving this (variables are this trivial due to experimenting purposes:
var a = false;
var b = false;
var condition = true;
if (condition) {
a = true;
} else {
b = true;
}
I took it as a code challenge with a colleague, join us if feeling like that, cheers :)
What about
var a =condition;
var b = !a;
You can use destructuring to assign true / false according to condition:
const condition = true;
const [a, b] = condition ? [true, false] : [false, true]
console.log({ a, b });
And you can optimize it to:
const condition = true;
const [a, b] = [condition, !condition]
console.log({ a, b });
And using default values, you can shorten it a bit more, although it's a slight abuse of the default values:
const condition = true;
const [a, b = !a] = [condition]
console.log({ a, b });
In many functions I have noticed the following pattern: function declares variables, combines it to the result and returns result. It is shown in this very simple example:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
or:
function fn() {
var a, b;
return a = 1,
b = 2,
a + b;
}
fn(); // 3
I would like to minimize this code and reduce it to the one statement. It could look like this:
function fn() {
return a = 1,
b = 2,
a + b;
}
However this code declares variables a, b in global scope which is not acceptable. Is it possible to do this in javascript?
Maybe this works for you, which is not advisable because of using assignment alogn with the comma operator.
function fn(a, b) { // declaration in local scope
return a = 1, b = 2, a + b; // return value with comma operator
}
A newer approach takes default values and returns just the addition of both.
fn = (a = 1, b = 2) => a + b;
What you are trying to do (declare using var and return in same statement) is not possible with JavaScript syntax.
The most concise you can get is your first option:
function fn() {
var a = 1,
b = 2;
return a + b;
}
fn(); // 3
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];
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.
Working on my first JS app, BlackJack, and have been stuck at this point for a while: what I'm trying to do is if var a is called from the array it could = 11 or 1 depending on the total value. Is there no way to change the value of an item in an array after you set up said array?
var j = 10;
var q = 10;
var k = 10;
var a;
var totalPlayer = 12;
var cards = [2, 2, ..., a, a, a];
function processIt() {
playerCard1 = cards[48]; //this is calling for var a form the array
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1; //this is calling for var a form the array
}
I have also tried converting it to a sting then back to a var, failed.
If I'm reading correctly, you've set up your array
var cards = [2, 2, ..., a, a, a];
and now you want to change all those a's?
Unfortunately (since a is a primitive) you'll have to manually change the values in your array that currently equal a, and set them to the updated value.
for (var i = 0, max = cards.length; i < max; i++)
if(cards[i] === a)
cards[i] = newValue;
EDIT
As hop points out, just be aware that if a is equal to 2, then all indexes in your array equal to 2 will be replaced—those first few indexes that you manually set to 2, and also those indexes at the end that you set to a. But since you say that a will either be 1 or 11, it looks like you've set things up in such a way that this won't be an issue.
You cannot do what you are expecting this way.
var a = 1;
var cards = [2, 2, a, a, a];
a = 5;
alert(cards); // This should print 2,2,5,5,5 is what you expect.
// But, it will only print 2,2,1,1,1
You can store all the indexes for which you set the value as 'a'. After all, you are constructing the array and it should be no hurdle for you.
In our case, you will have another array
var aIndexes = [2,3,4];
Then you can change the value of cards array like below.
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
for(var i =0; i< aIndexes.length; i++){
cards[i] = a;
}
The following line:
var cards = [2, 2, ..., a, a, a];
...copies the value of a into the last three array positions. Those values have no relationship with a itself. Changing a later has no effect on the array. It must be updated manually:
if (totalPlayer > 11) {
a = 1;
} else {
a = 11;
}
cards.splice(-3, 3, a, a, a);
var a;
…
var cards = [2, 2, ..., a, a, a];
puts the value of a at the time of creation of the Array instance as element of the array, not some sort of pointer to a. It is equivalent here to
var cards = [2, 2, ..., undefined, undefined, undefined];
You can either modify the array directly, as others have pointed out, or store references to an Object instance in the array (references are values). Modifying a property of that Object instance would modify it for all references to the Object instance then.
var a = {
toString: function () { return String(this.valueOf()); },
valueOf: function () { return this.value; }
};
// …
var cards = [2, 2, ..., a, a, a];
function processIt()
{
var playerCard1 = cards[48];
if (totalPlayer > 11)
{
a.value = 1;
}
else
{
a.value = 11;
}
var cpu1 = document.getElementById("cpu1");
cpu1.innerHTML = playerCard1;
}
Accessing a in string or numeric expression context would then yield the value of the value property of the Object instance referred to by a:
/* y + a.valueOf() */
var x = y + a;
/* z + a.toString() */
var y = z + String(a);
You must decide whether either approach makes sense in your case, as I do not know Blackjack well, and your question is rather confused.
BTW, you have forgotten to declare playerCard1 which causes it to leak into outer execution contexts or causes a runtime error (ES 5.x strict mode). I have fixed it for you. In general, you want to reduce the number of global variables to the absolute necessary minimum.