I want to extract a value from a variable. If its an array, I want the first element, and if not, I want the value of that variable. The value is a float, but I was wondering which of these are better in terms of performance, portability to non-floats, and of course short code and code readability
I want to use
value = variable[0] || variable
Its short and nice, is there any caveats is using this?
or I can do,
value = ([].concat(variable))[0]
This SO question says it's bad for performance.
And then, ofcourse, I can check if variable is an array or not in a few different ways, that is also mentioned in above question. Is there any better ways if the first one is not good?
Your value = variable[0] || variable will work, and will work reliably. Technically, if variable is a number primitive, what the JS engine has to do at that point is promote it to an object and then look up the 0 property on that object, but as you know it won't have one, that's okay.
The only cases where that may fail are if variable is null or undefined, because neither of those can be promoted to an object, and so the expression will throw. Provided you're okay with that, then you can use that. I'd comment it, though, because it's pretty odd-looking.
If you needed to defend against null and undefined, you could use the fact that == null will filter out both of those:
value = variable == null ? undefined : variable[0] || variable;
I'd comment that, too. :-)
Having this
value = variable[0] || variable
you may go to a trouble if the first element of the array is false. For example:
var arr = [false, 1, 2, 3];
value = variable[0] || variable; // <--- value is [false, 1, 2, 3]
So, I'll go with this:
var value = arr instanceof Array ? arr[0] : arr;
If you are not sure if the array is full then you should add one more check.
var value = arr instanceof Array && arr.length > 0 ? arr[0] : arr;
Related
I have an array filled with the names of variables like this:
var myVariables = [variable1,variable2,variable3,variable4];
Is there a simple way besides and each to test if all of these variables have been assigned a value (elsewhere in my code)?
I would suggest using Array.some, with that approach there is a chance you won't have to iterate the entire array:
const hasEmpty = myVariables.some(v => typeof v === 'undefined');
You could use the Array.prototype.some() method :
The some() method tests whether some element in the array passes the
test implemented by the provided function.
It could be more efficient than forEach method as it stops iterating (short circuit in a some way) as soon a element matches the condition.
For example to check that all elements are > 0, use some() with the reverse condition, that is : <=0.
var isFailed = [0, 1, 2, 3, 4].some(x => x <= 0);
For example, here, as soon the first iteration, some() exits and return false.
return myVariables.indexOf(undefined) === -1;
If one of your variable is not defined, this will throw a ReferenceError such as mentionned in top comments by Felix Kling. Otherwise if it has the value undefined then you can check if your array contains undefined values.
don't throw Reference Error
If you execute the code below you will get a ReferenceError since variable1 has never been defined.
const myArray = [variable1]
But this next code will just create an array with an undefined value in it, since the variable is declared:
let variable1
const myArray = [variable1]
check if undefined is included
With ES 2016 includes():
const isAllDefined = !myVariables.includes(undefined)
// use this boolean where you need it
I have two HTML elements both with data-final-figure attribute on them. Either one of those final figure on the elements can be assigned a value or be left empty, but can NOT be set in conflict with each other. Now I'm using a quite inefficient way to:
1) check if the first one is null, if it's not null, then put it into a variable;
2) then check if the second one isnull, if it's not, and the first one is null, then copy it back to the first data-final-figure attr; if it's not null and the first one is not null either, then check if they are assigned an identical value, if not, then they are conflicting and here we throw an error because both elements are specified a different value. If the second is null and the first one is not, then copy the first one's value to the second.
I dimly remember this algorithm in one of the textbook but can't put my finger on the name. It's not Hanoi tower I'm sure. Is there a better way to implement? Thanks.
Your algorithm can be simplified. Here's pseudo-code:
var1 = elem1.attribute
var2 = elem2.attribute
if (var1 && var2 && var1 != var2) {
report conflict
} else if (!var1 || !var2) { // one is null
value = var1 || var2; // Get the non-null value
var1.attribute = var2.attribute = value // Assign it to both
}
In ES5 whenever I want to get some property I need to first check that it exists like this:
if (typeof floob.flib !== 'undefined') {
// do something
}
even worse is that for nested properties you have to manually check for the existence of every property down the dotted path.
Is there a better way to do this in ES2015?
If it is just a single depth property name - you don't need typeof, you may just compare the value with undefined.
Your solution is prone to false negatives: it may think there is no a property with a given name, while there is one. Example: var o = { foo: undefined };
If you need to check if the path exists in the nested objects - you still need to implement recursion/loop/or use any library that does either for you.
ES2015 did not bring anything new to solve this problem easier.
If you have lodash available, you can use _.get(obj, path, defaultValue) (https://lodash.com/docs#get)
By using typeof,
typeof floob.flib === 'undefined'
equals to,
floob.flib === undefined
I assume you want to check whether floob.flib has a value, and if it does, you want to perform an operation with it.
However, in JS, there's almost simpler way to achieve this.
E.g.
if (floob.flib) {
// 'floob.flib' is NOT 'null', 'empty string', '0', false or 'undefined'
}
This also works well if you want to assign variable with ternary ( ?: ) operators.
var str = floob.flib ? 'exists' : 'does not exist';
Or even using logical OR ( || )
var str = floob.flib || '<= either null, empty, false, 0 or undefined';
Note that unless floob.flib does not produce ReferenceError exception, the code above should work just fine.
I have an array linking integers to objects:
var array = [];
array[3] = new Something();
array[42] = new OtherSomething();
array[84] = new SomethingAgain();
I want to check if an field exists in an array, and then use it if it does.
var field = array[row];
If the array doesn't contain any field with index row, then field will be set to undefined.
My question is: what is the best way to check its existence between:
if (field !== undefined) { /* Do stuff with field */ }
And:
if (field) { /* Do stuff with field */ }
The second solution is shorter, so it could be quicker to execute, because JavaScript is an interpreted scripting language. But in another hand, it might check for boolean value of field, or something like that...
What is your point on this ?
The array what you created is called a sparse array. You can read more about it in this answer.
The check
if (field !== undefined)
might not help if the actual value stored in the array itself is undefined. And this check
if (field)
will evaluate to be truthy if field is any one of the Truthy values. You can read more about the Truthiness and Falsiness of different values in this answer.
So, if you want to know if the array has a particular index, then you can use Object.prototype.hasOwnProperty, like this
var array = [];
array[1] = undefined;
console.log(array[0]);
// undefined
console.log(array[1]);
// undefined
console.log(array.hasOwnProperty(0));
// false
console.log(array.hasOwnProperty(1));
// true
Here the element at 1 is defined to be undefined, but since 0 is not defined at all, by default, JavaScript returns undefined.
The hasOwnProperty call checks if the current object really has the index 0 and 1.
"Best" is a fairly subjective term, so let's throw some objective criteria at it:
Which is faster?
In a way that you'll notice in the real world, neither. But if you really want to know, measure your specific code on the engines you want to support.
Which is easier to read?
This is probably subjective as well. The second form is extremely common in JavaScript, FWIW.
Which is less typing?
The second form is obviously a lot shorter than the first.
Which is more reliable?
Given your use case, they're equally reliable, because you're either not storing an entry in the array at all, or storing a non-null object reference.
In similar but different use cases, you might need to be wary of the difference: The first form will only be true for an entry that exists and doesn't have the value undefined in it. The second form will be true for anything that isn't falsey. There are several falsey values: null, undefined, 0, "", NaN, and of course, false. So you wouldn't use the second form to decide whether there was a number at a position in the array, since 0 is a number but if (0) won't go into the body of the if.
Speaking of ambiguity, note that comment about "...true for an entry that exists and doesn't have the value undefined in it..." Neither of the examples you gave differentiates between an entry that doesn't exist and an entry that exists with the value undefined. If you need to differentiate those at some point (again, not for the use case you mentioned), you'd use hasOwnProperty on the array: if (array.hasOwnProperty(row))
The second solution is shorter, so it could be quicker to execute, because JavaScript is an interpreted scripting language
This is a mistaken assumption. Most modern JavaScript engines are just-in-time optimizing compilers. V8 (the engine in Chrome), for instance, is a two-stage optimizing compiler: On the first pass, it turns your JavaScript into machine code quickly, and then if it identifies hotspots (bits of code that run a lot), it goes back and does more aggressive optimization there.
I'll give you this example. Hope it helps you feel clearer.
var arr = [];
arr[0] = 0;
arr[1] = undefined;
arr[2] = null;
arr[3] = NaN;
arr[4] = '';
arr[5] = false;
arr[11] = 1;
arr[12] = [];
arr[13] = {};
arr[14] = 'hello';
arr[15] = true;
if(arr[0]) //false but exists
if(arr[1]) //false but exists
if(arr[2]) //false but exists
if(arr[3]) //false but exists
if(arr[4]) //false but exists
if(arr[5]) //false but exists
if(arr[6]) //false and not exist
if(arr[7]) //false and not exist
if(arr[8]) //false and not exist
if(arr[9]) //false and not exist
if(arr[10]) //false and not exist
if(arr[11]) //true and exists
if(arr[12]) //true and exists
if(arr[13]) //true and exists
if(arr[14]) //true and exists
if(arr[15]) //true and exists
In general, I recommend you to use the second solution for checking existence since it's shorter and easier to read. However, it still strongly depends on your case. Make sure that your choice is not going to fail in any unexpected situations.
I have a 2nd level array, that at a cetain point in the code can be ether undefined or contain value. If it is undefined I need to define it, without giving it any value.
this is what i did:
arr[arr2["stripID"]] = typeof(arr[arr2["stripID"]]) === 'undefined' ? [] : arr[arr2["stripID"]];
is there a better or shorter way?
arr[arr2["stripID"]] = arr[arr2["stripID"]] || [];
Should do what you want.
The || operator returns the first truthy value in the expression. Because an array is truthy, and the only other value it can be is undefined (falsy), this'll work fine.