Quick question. Let's say I've got a Stack, where I pop things.
var stack = [];
stack.push(2); // stack is now [2]
stack.push(5); // stack is now [5]
How do I read the last element, since, let's say I don't have the number of pops? For example a click function adds a variable to the stack and I need to use the last added variable, which command do I use?
And also, if I want to check all the Objects of the stack with another variable is it simply a for-loop with
stack[i] != x
Thanks in advance.
To assign the last element to a variable:
var x = stack[stack.length - 1]
If your array elements are objects you'll want to check a property of an object against a variable.
For example you might want to see if there's one or more objects with a key/value pair of 'number'/2 in the array. You might use some to check:
var x = 2;
var arr = [{ number: 1 }, { number: 2 }, { number: 3 }];
var some = arr.some(function (el) {
return el.number === x;
}); // true
Be sure to check out the various array methods on MDN.
Read last element in array
stack[stack.length-1]
stack[i] !== x is better comparison
!= won't catch that difference for instance null != undefined
These are connected with truthy and falsy values in javascript.
Related
When I console.log my array it shows that the length is zero. I checked that it was an array using Array.isArray which returned true. Also printed out the array values to make sure they exist and it shows in the console:
[]
0: "a"
1: "b"
2: "c"
3: "d"
length: 4
__proto__: Array(0)
I see that __proto__: Array(0) and I'm assuming this means it's a 0 length Array but how do I make it non-zero length so that I can iterate through it?
A thought I had is that this function might be asynchronous but I'm not really sure how to work around that.
Code for reference:
var list=[]
//getting data from a database
snapshot.forEach(function (node) {
list.push(node.val())
console.log(node.val()) //values print out
})
console.log(list) //array is length zero
I'm basically trying to add a for loop after this code to read through each value and use it for something else. However I can't iterate through the array because it registers as empty.
For anyone else who is facing similar issue:
You are very likely populating the array within an asynchronous function.
function asyncFunction(list){
setTimeout(function(){
list.push('a');
list.push('b');
list.push('c');
console.log(list.length); // array length is 3 - after two seconds
}, 2000); // 2 seconds timeout
}
var list=[];
//getting data from a database
asyncFunction(list);
console.log(list.length) //array is length zero - after immediately
console.log(list) // console will show all values if you expand "[]" after two seconds
__proto__ is not your object, it is the accessor for the prototype.
The __proto__ property of Object.prototype is an accessor property (a
getter function and a setter function) that exposes the internal
[[Prototype]] (either an object or null) of the object through which
it is accessed.
The use of __proto__ is controversial, and has been discouraged.
I had the same problem and when I logged the variable snapshot as shown below the variable was logged after most of the logic after it was executed, since it was available later, that is why the Array values are not accessible.
let admins = []
adminRef.once('value',(snapshot)=>{
console.log(snapshot);
snapshot.forEach(data=>{
admins.push(data.key);
})
})
So changed it so that the logic underneath was executed once the snapshot variable was available
adminRef.once('value',(snapshot)=>{
if(snapshot){
console.log(snapshot);
snapshot.forEach(data=>{
admins.push(data.key);
})}
I'd need to see more of your code but this is something that you'd want.
var arr = [1, 3, 5, 6];
console.log(arr.length);
for (var i = 0; i < arr.length; i++){
console.log(arr[i]);
}
Similar problem and not a solution.
printVertices(){
console.log(Array.isArray(this.vertices), this.vertices)
let head = "<head> "
this.vertices = []
console.log(this.vertices)
this.vertices.map(data => head += data.data + " ")
head += "<tail>"
console.log(head)
}
}
and as you can see from my terminal look at the top! it shows Array.isarray(myarray) is true and console.log of this.vertices is the linkedlist then at the bottom it prints am empty array. However this.vertices prints the linkedList to the console
I don't understand the purpose of this = sign on the sixth line in the code block below. I understand how the argument grabs each index number of the array, I just don't understand why chineseFood[array[0]] = array[array.length-1]; In other words, I don't get the purpose of the equal sign as if it were almost comparing each other to be stored in the empty object that is stored in the variable chineseFood. Could someone please clarify? It would be much appreciated.
function transformFirstAndLast(array) {
var chineseFood = {};
//takes 1st element (at index 0) and sets it to the last element (nth index): array(length-1)
chineseFood[array[0]] = array[array.length - 1];
return chineseFood;
}
console.log( transformFirstAndLast(['Orange', 'Lemon', 'Pork', 'Chicken']) );
Output Below
{Orange: "Chicken"}
The equals sign is not comparison, it is assignment. chineseFood is an object, which means that it can be treated like a dictionary, and its properties can be accessed using the [] operator instead of the . operator:
myObj = {
foo: "bar"
};
console.log(myObj["foo"]); // bar
console.log(myObj.foo); // bar
Likewise, you can also assign properties this way:
myObj = {};
myObj["foo"] = 3;
console.log(myObj["foo"]); // 3
console.log(myObj.foo); // 3
This is what your code is doing. It is retrieving the value of array[array.length-1], which is "Chicken". Then it is assigning this value to the property of chineseFood that has the name represented by array[0], which happens to be "Orange". Thus, the property named Orange on chineseFood is set to array[array.length - 1], which is why chineseFood evaluates to {Orange: "Chicken"}.
This method of accessing properties is especially useful when you don't know the name of the property you will be changing in advance, as is the case with this code, or when you want to create properties that have names that would otherwise be illegal:
myObj = {
".you can't usually use with spaces or start w/ periods": false
};
myObj[".you can't usually use with spaces or start w/ periods"] = true;
console.log(myObj[".you can't usually use with spaces or start w/ periods"]);
// there is no way to read this property the normal way
Basically what is does is:
your object is :
var obj = {Orange: "Chicken"};
And Your array is :
var arr = ['Orange','Lemon','Pork','Chicken']
What this line says is pick first element of the array and check for this prop in object and change its value to last element of array, here:
arr[0] = "orange";
So this line :
obj[arr[0]] can be seen as obj['orange'].
After that you change its value:
Obj[arr[0]] = arr[arr.length-1] which can be written as obj['orange'] = 'chicken'
I'm working through Eloquent JavaScript chapter 7 and I am trying to work out the part with the forEach within the World.prototype.turn function:
http://eloquentjavascript.net/07_elife.html#h_6OGIzAd5Tr
World.prototype.turn = function() {
var acted = [];
this.grid.forEach(function(critter, vector) {
console.log(critter);
if (critter.act && acted.indexOf(critter) == -1) {
acted.push(critter);
this.letAct(critter, vector);
}
}, this);
};
I understand what this is doing (I think), it is looping over each item in the Grid array and for every critter that is found (all critters have an act method within their prototype), it is checking the indexOf in the local array acted.
If it doesn't exist (-1), it is pushing it in.
My question is, how is each critter unique? When I console.log(critter) I get identical results: { direction: 'e', originChar: 'o' }.
How does this not always return -1 as the indexOf() after the first critter is pushed to the array?
Is it because within elementFromChar, every critter is created from the BouncingCritter constructor with new?
Thanks in advance, just trying to learn this thoroughly and try to understand it properly :)
In Javascript objects have an inherent uniqueness, so that
var x = { foo: 'bar' };
var y = { foo: 'bar' };
x !== y;
// But
var x = { foo: bar }
x === x;
It's a complex subject which you can read more about here. In essence the indexOf is checking for that exact object, regardless of it's property values.
Given following array:
var arr = [undefined, undefined, 2, 5, undefined, undefined];
I'd like to get the count of elements which are defined (i.e.: those which are not undefined). Other than looping through the array, is there a good way to do this?
In recent browser, you can use filter
var size = arr.filter(function(value) { return value !== undefined }).length;
console.log(size);
Another method, if the browser supports indexOf for arrays:
var size = arr.slice(0).sort().indexOf(undefined);
If for absurd you have one-digit-only elements in the array, you could use that dirty trick:
console.log(arr.join("").length);
There are several methods you can use, but at the end we have to see if it's really worthy doing these instead of a loop.
An array length is not the number of elements in a array, it is the highest index + 1. length property will report correct element count only if there are valid elements in consecutive indices.
var a = [];
a[23] = 'foo';
a.length; // 24
Saying that, there is no way to exclude undefined elements from count without using any form of a loop.
No, the only way to know how many elements are not undefined is to loop through and count them. That doesn't mean you have to write the loop, though, just that something, somewhere has to do it. (See #3 below for why I added that caveat.)
How you loop through and count them is up to you. There are lots of ways:
A standard for loop from 0 to arr.length - 1 (inclusive).
A for..in loop provided you take correct safeguards.
Any of several of the new array features from ECMAScript5 (provided you're using a JavaScript engine that supports them, or you've included an ES5 shim, as they're all shim-able), like some, filter, or reduce, passing in an appropriate function. This is handy not only because you don't have to explicitly write the loop, but because using these features gives the JavaScript engine the opportunity to optimize the loop it does internally in various ways. (Whether it actually does will vary on the engine.)
...but it all amounts to looping, either explicitly or (in the case of the new array features) implicitly.
Loop and count in all browsers:
var cnt = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] !== undefined) {
++cnt;
}
}
In modern browsers:
var cnt = 0;
arr.foreach(function(val) {
if (val !== undefined) { ++cnt; }
})
Unfortunately, No. You will you have to go through a loop and count them.
EDIT :
var arrLength = arr.filter(Number);
alert(arrLength);
If the undefined's are implicit then you can do:
var len = 0;
for (var i in arr) { len++ };
undefined's are implicit if you don't set them explicitly
//both are a[0] and a[3] are explicit undefined
var arr = [undefined, 1, 2, undefined];
arr[6] = 3;
//now arr[4] and arr[5] are implicit undefined
delete arr[1]
//now arr[1] is implicit undefined
arr[2] = undefined
//now arr[2] is explicit undefined
Remove the values then check (remove null check here if you want)
const x = A.filter(item => item !== undefined || item !== null).length
With Lodash
const x = _.size(_.filter(A, item => !_.isNil(item)))
I've got an array
var assoc_pagine = new Array();
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
I tried
if (assoc_pagine[var] != "undefined") {
but it doesn't seem to work
I'm using jquery, I don't know if it can help
Thanks
Use the in keyword to test if a attribute is defined in a object
if (assoc_var in assoc_pagine)
OR
if ("home" in assoc_pagine)
There are quite a few issues here.
Firstly, is var supposed to a variable has the value "home", "work" or "about"? Or did you mean to inspect actual property called "var"?
If var is supposed to be a variable that has a string value, please note that var is a reserved word in JavaScript and you will need to use another name, such as assoc_var.
var assoc_var = "home";
assoc_pagine[assoc_var] // equals 0 in your example
If you meant to inspect the property called "var", then you simple need to put it inside of quotes.
assoc_pagine["var"]
Then, undefined is not the same as "undefined". You will need typeof to get the string representation of the objects type.
This is a breakdown of all the steps.
var assoc_var = "home";
var value = assoc_pagine[assoc_var]; // 0
var typeofValue = typeof value; // "number"
So to fix your problem
if (typeof assoc_pagine[assoc_var] != "undefined")
update: As other answers have indicated, using a array is not the best sollution for this problem. Consider using a Object instead.
var assoc_pagine = new Object();
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
var assoc_pagine = new Array();
assoc_pagine["home"]=0;
Don't use an Array for this. Arrays are for numerically-indexed lists. Just use a plain Object ({}).
What you are thinking of with the 'undefined' string is probably this:
if (typeof assoc_pagine[key]!=='undefined')
This is (more or less) the same as saying
if (assoc_pagine[key]!==undefined)
However, either way this is a bit ugly. You're dereferencing a key that may not exist (which would be an error in any more sensible language), and relying on JavaScript's weird hack of giving you the special undefined value for non-existent properties.
This also doesn't quite tell you if the property really wasn't there, or if it was there but explicitly set to the undefined value.
This is a more explicit, readable and IMO all-round better approach:
if (key in assoc_pagine)
var is a statement... so it's a reserved word... So just call it another way.
And that's a better way of doing it (=== is better than ==)
if(typeof array[name] !== 'undefined') {
alert("Has var");
} else {
alert("Doesn't have var");
}
This is not an Array.
Better declare it like this:
var assoc_pagine = {};
assoc_pagine["home"]=0;
assoc_pagine["about"]=1;
assoc_pagine["work"]=2;
or
var assoc_pagine = {
home:0,
about:1,
work:2
};
To check if an object contains some label you simply do something like this:
if('work' in assoc_pagine){
// do your thing
};
This worked for me
if (assoc_pagine[var] != undefined) {
instead this
if (assoc_pagine[var] != "undefined") {
TLDR; The best I can come up with is this: (Depending on your use case, there are a number of ways to optimize this function.)
function arrayIndexExists(array, index){
if ( typeof index !== 'number' && index === parseInt(index).toString()) {
index = parseInt(index);
} else {
return false;//to avoid checking typeof again
}
return typeof index === 'number' && index % 1===0 && index >= 0 && array.hasOwnKey(index);
}
The other answer's examples get close and will work for some (probably most) purposes, but are technically quite incorrect for reasons I explain below.
Javascript arrays only use 'numerical' keys. When you set an "associative key" on an array, you are actually setting a property on that array object, not an element of that array. For example, this means that the "associative key" will not be iterated over when using Array.forEach() and will not be included when calculating Array.length. (The exception for this is strings like '0' will resolve to an element of the array, but strings like ' 0' won't.)
Additionally, checking array element or object property that doesn't exist does evaluate as undefined, but that doesn't actually tell you that the array element or object property hasn't been set yet. For example, undefined is also the result you get by calling a function that doesn't terminate with a return statement. This could lead to some strange errors and difficulty debugging code.
This can be confusing, but can be explored very easily using your browser's javascript console. (I used chrome, each comment indicates the evaluated value of the line before it.);
var foo = new Array();
foo;
//[]
foo.length;
//0
foo['bar'] = 'bar';
//"bar"
foo;
//[]
foo.length;
//0
foo.bar;
//"bar"
This shows that associative keys are not used to access elements in the array, but for properties of the object.
foo[0] = 0;
//0
foo;
//[0]
foo.length;
//1
foo[2] = undefined
//undefined
typeof foo[2]
//"undefined"
foo.length
//3
This shows that checking typeof doesn't allow you to see if an element has been set.
var foo = new Array();
//undefined
foo;
//[]
foo[0] = 0;
//0
foo['0']
//0
foo[' 0']
//undefined
This shows the exception I mentioned above and why you can't just use parseInt();
If you want to use associative arrays, you are better off using simple objects as other answers have recommended.
if (assoc_pagine.indexOf('home') > -1) {
// we have home element in the assoc_pagine array
}
Mozilla indexOf
function isset(key){
ret = false;
array_example.forEach(function(entry) {
if( entry == key ){
ret = true;
}
});
return ret;
}
alert( isset("key_search") );
The most effective way:
if (array.indexOf(element) > -1) {
alert('Bingooo')
}
W3Schools