What is the interpretation of this line in Javascript.
var x[],matrix[],n;
...
n = (matrix = x) && matrix.length;
Despite I searched for it, I couldn't find any tips.
Thank you
It does this:
Assigns the value of x to matrix; the result of the matrix = x expression is the value that was assigned (this is true of all assignment expressions). Let's call that value "x-value". I don't want to call it x from here on out, because x is only evaluated once.
If x-value is truthy1 (coerces to true), it assigns matrix.length to n; otherwise, assigns x-value to n.
So for instance, if x is [], the code sets matrix to point to the same empty array x does and sets n to 0 (matrix.length after the assignment). Other examples (I'd written these before you edited your question): If x is "foo", it sets matrix to "foo" and sets n to 3 (the length of matrix). If x is "" (a falsy value), it sets matrix to "" and sets n to "". If x is {foo:"bar"}, it sets matrix to refer to that same object and sets n to undefined (since the object has no length property). You get the idea.
#2 above comes about because && is not just a simple logical AND operator. a && b works like this:
Evaluate a to get its value; let's call that a-value
If a-value is falsy, the result of the && operator is a-value
Otherwise, evaluate b and make that the result of the && operator
1 "Truthy" values are any values that aren't "falsy." The falsy values are 0, null, undefined, "", NaN, and of course, false.
We can interpret it as some pseudocode like this:
var x[],matrix[],n;
...
matrix = x
if(x is not in [null, false, 0, undefined, "NaN",""])
n = matrix.length
else
n = x
(matrix = x) is the assignment operation of x into a variable matrix. Here x is an array, hence the result of this operation gives a truthy value, and hence the later part takes place.
E.g. if
var x, matrix = [], n;
n = (matrix = x) && matrix.length;
won't work as the (matrix = x) is a falsy operation. n gets assigned undefined (because that's the value x has).
Related
Can anyone explain the meaning of the assign operator? What does it mean?
It came out as true but I'm unclear on how we reached to there.
Thanks!
var x = 0 !=1;
An assignment operator assigns a value to its left operand based on the value of its right operand. In this case true will be assigned to the variable x as 1!=0 (1 not equal-to 0) is true.
Order of operations (var x = (0 != 1))
Imagine you computed just 0 != 1. This is evidently a true statement, so this would evaluate to true. If you set x to the evaluation of 0 != 1, then you receive var x = true.
The following code uses the reduce method. It outputs the number of times an element appears in the array. If element appears once then it only outputs 1, otherwise if it is a repeated item then it it is added..
let a = ["a", "b", "c", "a", "b"]
const t = a.reduce((aa, ll) => {
const count = aa[ll];
count
?
aa[ll] = count + 1 :
aa[ll] = 1
return aa
}, {})
console.log(JSON.stringify(t))
// output
// { "a":2, "b":2, "c":1 }
Question is regarding the condition in the ternary operation, specifically the count variable. How is the count variable able to resolve true or false.
The concept is called "Truthy" and "Falsy" respectively. Ie anything that is different from false, 0, -0, 0n, NaN, null, undefined and "" (empty string) can be evaluated to true in Javascript
So your assign var counter = aa[ll] to be the value of the key ll in object aa. That's either a number or undefined. If it's a number !== 0 it's a truthy, if it's 0 or undefined it's falsy. Thus it can be used in a ternary operatator. Depending on the value of counter either the value of the first or the second assignment will be returned (but ignored). The return value of an assignment is always the value of the right hand side ...
While you can use also assignments in the expressions of a ternary operator, I personally wouldn't use it that way but write this assignment as follows
const t = a.reduce((aa, ll) => {
aa[ll] = (aa[ll] || 0) + 1;
return aa
}, {})
(aa[ll] || 0) will return the value of aa[ll] if it's a truthy or 0 otherwise. Thus, in your case, the result of this expression will always be a number >= 0. Then you increase the result by 1 (for the currenct occurence of ll) and assign it back to aa[ll]. This is much shorter than your original code and IMHO much more readable
Heres the answer I found.
"A javascript object consists of key-value pairs where keys are unique. If you try to add a duplicate key with a different value, then the older value for that key is overwritten by the new value."
basically the count variable was checking to see if the new property already exists.
Im brand new to javascript. I simply have an exercise where i need the array numbers to add each index to the next one.
The result should be:
var result = [4,8,15,21,11];
I tried something like this. It works on the first 4 indexes, however gives NaN on last since it doesnt have a next number to add to.
var numbers = [1, 3, 5, 10, 11];
var result = numbers.map((x, index) => x + numbers[index + 1])
console.log(result)
Is there any smarter way to do this and how do i get index 4 to stay as 11? And please explain as im trying to learn.
That's a perfectly valid way to do it. You can handle the last index by taking advantage of the fact that numbers[index] will be undefined (not an error) if index is beyond the end of the array, and undefined is a falsy value, so you can use || 0 to use 0 instead of undefined if it's there:
var result = numbers.map((x, index) => x + (numbers[index+1] || 0));
Live Example:
var numbers = [1, 3, 5, 10, 11];
var result = numbers.map((x, index) => x + (numbers[index + 1] || 0));
console.log(result);
|| is the logical OR operator, but it's a bit special in JavaScript: It evaluates its left-hand operand and, if that value is truthy¹, takes that value as its result; if the left-hand is falsy, the operator evalutes the right-hand operand and takes that value as its result.
In ES2020+ you can use the new nullish coalescing operator (??) instead of ||:
var result = numbers.map((x, index) => x + (numbers[index+1] ?? 0));
That will only use the 0 if numbers[index] is null or undefined, rather than if it's any falsy value.
¹ "truthy" and "falsy" - A truthy value is a value that evaluates to true when used as a condition (for instance, if (x) or x || y); a falsy value is a value that evalutes to false. The falsy values are 0, "", NaN, null, undefined, and of course, false. All other values are truthy. (Except there's a special case on browsers: document.all is falsy for legacy reasons.)
Can some one please explain to me in a layman's what is happening in the loop as it iterates to produce the statement (the objects properties are in an array).
var o = {x:1, y:2, z:3};
var a = [], i = 0;
for (a[i++] in o)
{
console.log(o);
}
This is how the for/in loop is evaluated:
for each property in object o
assign the property name to the left hand side, that is a[i++]
Initially i = 0, so:
a[0] will get x. // notice it gets the property name, not its value
a[1] will get y.
a[2] will get z.
NOTE: i++ is equal to i = i + 1.
The previous code is equivalent to the following:
var o = {x:1, y:2, z:3};
var a = []
var i = 0;
for (propertyName in o)
{
a[i] = propertyName;
i = i + 1;
console.log(o);
}
It assigns an object with three keys (x,y,z) to o. It assigns an empty array to a, and the number 0 to i.
The for ( in ) loop will iterate over an object's properties, but first the condition is evaluated.
i++ is evaluated first. The ++ is a post-increment operator and is notorious for people getting the damn thing wrong. Douglass Crockford (search for him) suggests not using it. It returns the value stored in i (which was 0) then increments it.
So now i is storing 1, and we're evaluating a[0], which is accessing an element in an array, except... that array is empty (we're accessing an undefined value).
It now looks at in o, which iterates through the keys in o, which there are 3 of. Thus, it iterates the loop three times. Each time it then logs the object to the console.
Whatever this code is, I'd suggest replacing it. It shouldn't be something you want to see in code. It's confusing and surely doesn't do anything meaningful.
I have been doing some reading lately one article I read was from Opera.
http://dev.opera.com/articles/view/javascript-best-practices/
In that article they write this:
Another common situation in JavaScript
is providing a preset value for a
variable if it is not defined, like
so:
if(v){
var x = v;
} else {
var x = 10;
}
The shortcut notation for this is the
double pipe character:
var x = v || 10;
For some reason, I can't get this to work for me. Is it really possible to check to see if v is defined, if not x = 10?
--Thanks.
Bryan
That Opera article gives a poor description of what is happening.
While it is true that x will get the value of 10 if v is undefined. It is also true that x will be 10 if v has any "falsey" value.
The "falsey" values in javascript are:
0
null
undefined
NaN
"" (empty string)
false
So you can see that there are many cases in which x will be set to 10 besides just undefined.
Here's some documentation detailing the logical operators. (This one is the "logical OR".) It gives several examples of its usage for such an assignment.
Quick example: http://jsfiddle.net/V76W6/
var v = 0;
var x = v || 10;
alert( x ); // alerts 10
Assign v any of the falsey values that I indicated above, and you'll get the same result.
var x = v || 10;
That operator (the "logical" or "short-circuit" OR operator) would normally check the value of v, and if it is a "falsy" value (i.e. it would fail as a condition used in an if statement), 10 becomes the value of x, otherwise v does (and if 10 were a function, it would never be executed).
undefined, null, and 0 are all examples of falsy values that a variable can hold (yes, even the first one), and the operator (or if statement) acts accordingly. In contrast, all objects and arrays (not including null) are "truthy" values, which allows for such things as this (used in the Google Analytics tracker code):
var _gaq = _gaq || []; // Makes a new array _gaq if it is not already there
However, if the referenced variable is not even declared anywhere within the scope chain, then a JavaScript exception will occur.
One way to avoid this is by declaring all your global variables from the start:
var iAmAGlobalVariable; // Holds the value undefined by default
If this is not possible, you should use the typeof operator. It does not attempt to evaluate its operand, and thus an exception will not occur:
var x;
if(typeof v != 'undefined' && v) {
x = v;
} else {
x = 10;
}
Or even better, if you know that the variable would be a global variable, you can treat it as a property of the global (window) object:
var x = window.v || 10;
If v evaluates to false (for example, 0, null, false) then it won't work. You can manually check for undefined:
var x = v !== undefined ? v : 10;
I would use triple equals with ternary in a function for this.
function myTest(x){
return x === undefined ? true: false;
}
Only returns true if x is undefined
See
(http://www.impressivewebs.com/why-use-triple-equals-javascipt/)
and
(http://jsfiddle.net/V76W6/)
I would just use a try-catch
var x = 0;
try
{
x = v;
}
catch(err)
{
x = 10;
}
Here is how to get it working:
var v; //declare v as undefined
// v = 5; //if uncommented x will be 5
var x = v || 10;
alert(x); //output: 10
http://jsfiddle.net/uLLtu/1/