JavaScript array indices start at 0, not 1. The .push() method adds an element at the end of the array, which in the case of an empty array (as yours is when your loop begins) will be array element 0.
Your loop inserts the value 1 at array index 0, the value 2 at array index 1, and so forth up to the value 10 at array index 9.
Each of your console.log(ar[i]) statements is trying to log a value from an index one higher than the highest element index, and those elements will always be undefined. So the console logs the value undefined ten times.
You can log the last element of an array like this:
console.log(ar[ar.length-1]);
Or in your case where you (now) know that i will be one higher than the index that .push() used:
console.log(ar[i-1]);
Answer from nnnnnn on Stack OverflowJavaScript array indices start at 0, not 1. The .push() method adds an element at the end of the array, which in the case of an empty array (as yours is when your loop begins) will be array element 0.
Your loop inserts the value 1 at array index 0, the value 2 at array index 1, and so forth up to the value 10 at array index 9.
Each of your console.log(ar[i]) statements is trying to log a value from an index one higher than the highest element index, and those elements will always be undefined. So the console logs the value undefined ten times.
You can log the last element of an array like this:
console.log(ar[ar.length-1]);
Or in your case where you (now) know that i will be one higher than the index that .push() used:
console.log(ar[i-1]);
"10 undefined" means that the console showed "undefined" 10 times.
As thefourtheye says in his comment, you're pushing the value i but the index of the element that you just pushed onto the end of the array is i - 1. This means that each time you console.log(ar[i]) you're logging something that's not yet defined.
This is all because the first element in the array is ar[0], not ar[1]. You can fix your problem by logging like so: console.log(ar[ i - 1 ]);
Videos
If I am accessing an index of an array based on a variable, I would first want to check that the index exists.
My understanding is that if I try to access an index outside of the array's range, I will get a value of 'undefined.' So,
(typeof array[i] === 'undefined')
should return true if array[i] does not exist.
Would it also be possible, because undefined is falsey, to get the same result with
!array[i]
?
Edit: Thanks for the help!
array[index] == 'undefined' compares the value of the array index to the string "undefined".
You're probably looking for typeof array[index] == 'undefined', which compares the type.
You are checking it the array index contains a string "undefined", you should either use the typeof operator:
typeof predQuery[preId] == 'undefined'
Or use the undefined global property:
predQuery[preId] === undefined
The first way is safer, because the undefined global property is writable, and it can be changed to any other value.
This is because you are adding extra elements to an array. Take this code, for instance:
var a = []; // empty array
a[1] = 'foo'; // don't set a[0]
console.log(a.length); // gives 2
Javascript will always "fill in" gaps in the list of array keys. If you miss some out, Javascript will fill in the blanks with undefined.
Rather than adding the element to your array by the key name, just push it onto the end of the array:
imageArray.push(cboxes[i].value);
You get undefined because you're skipping indexes in imageArray. If the first checkbox isn't checked, it won't put anything in index 0, then because the second checkbox is checked, the first entry is placed into index 1.
When you iterate it doesn't skip those missed indexes if there is an index with a value after it, they just don't have a set value so it comes back as undefined.
You could change this line:
imageArray[i] = cboxes[i].value;
to:
imageArray.push(cboxes[i].value);
That way it won't skip indexes when there are unchecked checkboxes.
So from what I could tell, it's calling Array() as if it was passed 10 arguments, but since it doesn't define any of those "integer properties", it's as if it was passed 10 undefined arguments. Is that correct?
Yes, exactly. It's doing this:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
var barr = new Array(10); console.log(barr);...
console.log(arr.map(function(item) { return 'hi';})); console.log(barr.map(function(item) { return 'hi';}));I wanted to know why the map function didn't work for the second one.
Because map, forEach, and similar only visit properties that actually exist. As you said, there's a big difference between.
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
// Or `var arr = Array.apply(null, {length: 10});
and
var barr = new Array(10);
In the first example, arr has 10 entries, each of which has the value undefined. In the second example, barr has no entries and a length of 10. So in the first one, map will visit the properties, because they exist. In the second one, it won't, because they don't.
Recall that standard arrays in JavaScript aren't really arrays at all (disclosure: that's a post on my blog), they're objects with some special behavior. As such, they're inherently sparse:
var a = [];
a.length = 10000;
a doesn't have 10,000 entries. It has no entries. It's just that its length property is 10000.
You can tell whether the property exists by using hasOwnProperty or in. Compare:
var barr = new Array(10);
console.log(barr.hasOwnProperty(0)); // false
console.log(0 in barr); // false
to:
var arr = Array.apply(null, {length: 10});
console.log(arr.hasOwnProperty(0)); // true
console.log(0 in arr); // true
And
Array.applyworks because it asks{length: 10}what its property0is, receivesundefined, and so assignsundefinedto the property0of the array it's constructing, and so on. Is my reasoning correct?
Yes, although to be clear, it's apply that's asking what property 0 is, and then it's using that as the first argument when calling Array. It's Array that then takes the first argument's value and assigns it to the 0 property on the array it's creating.
And is there really no less hackish way to define an array which contains undefined integer properties for each index within its range, rather than having no integer properties at all?
Only slightly: ES2015 adds Array.from, which accepts an array-like object and returns a true array (optionally mapping the entries). So that would be:
var arr = Array.from({length:10});
It's rare to need to do that, as opposed to simply a = new Array(bigNumberHere); or a = []; a.length = bigNumberHere. E.g., many times you don't care if the property doesn't exist or exists with the value undefined. Sometimes you do, but to give you perspective, I've been writing JavaScript professionally for 20 years, fairly intensively the last 8, and I've probably cared, oh, once or twice, tops.
You mentioned that in the specific case you were dealing with, it was combined with map, so Array.from would take the place of both:
var arr = Array.from({length: 10}, function() { return "hi"; });
...yields
["hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi"]
Although Array.from is new in ES2015, it can be shimmed/polyfilled on older JavaScript engines.
Is that correct?
Yes
you can also use any kind of object which is array-like, so in practice this means it's going to have a property length and integer properties in the range (0...length).
It says that you can pass a duck-type of an array: an object that has a sort of interface:
- a length property (for iteration)
- optional: some integer properties (the values)
This will be treated as an Array. So passing a { length: 10 } is like pass a real array [undefined,undefined,undefined,..] where each index is created and has value undefined.
So the first code row:
var arr = Array.apply(null, {length: 10});
is interpreted as:
var arr = Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
So my current guess is that arr is an array which contains as integer properties 10 variables which each have the value of undefined and barr is an array which, although it has a length of 10, has no integer properties.
Yes.
var test = Array(10);
it outputs: [undefined x10] <-- no indexes, only a simple property 'length' unaligned with the real content, but useful for retrieve it and do some size condiderations.
test[2] = undefined;
it outputs: [undefined x2, undefined, undefined x7] <-- no indexes except for the position '2' that has a value: undefined.
I've been working on this memory game for college. Its a "match the cards" style of game. You have a grid of playing cards, you need to flip them and find the pairs.
I have a function, pickCards() that loops a fixed number of times. Each iteration, it selects a random card from the array and adds it to an array "cardsPicked". Below is the code for the function. I've removed some stuff to make it more readable (the issue still exists in the below code).
// Picks the cards to display from all the available cardsfunction pickCards(allCards, numberToPick) {let cardsPicked = [];// Loops and appends a random card to the cardsPicked arrayfor(let i = 0; i < Math.floor(numberToPick/2); i++) {let card = allCards[Math.floor(Math.random() * allCards.length)]
cardsPicked.push(card);}return cardsPicked;}
If I log cardsPicked at the very end of the function, it returns an array. Occasionally (maybe 50% of the time) some of the values are undefined.
I added a console.log before the cardsPicked.push(card) to check if the card is defined, it is. The log displays the card perfectly (even when the log I've talked about above has undefined values).
The weird thing is, I also added a console.log(cardsPicked) after the cardsPicked.push(card), and it displays the cardsPicked array without any undefined elements. It's just at the end of the function that I'm getting the undefined elements.
In other words:
// Picks the cards to display from all the available cardsfunction pickCards(allCards, numberToPick) {let cardsPicked = [];// Loops and appends a random card to the cardsPicked arrayfor(let i = 0; i < Math.floor(numberToPick/2); i++) {let card = allCards[Math.floor(Math.random() * allCards.length)]
console.log(card) <-- displays the card finecardsPicked.push(card);console.log(cardsPicked) <-- displays no undefined values
}console.log(cardsPicked) <-- displays with undefined valuesreturn cardsPicked;}
Some information that might be helpful:
I know this is JS, but if it were TypeScript, the allCards array is of the below type:
type Card = {cardName: str // "Ace of Spades", "Two of Hearts", etccardImg: str // "img/AS.png", "img/2H.png", etcisFlipped: boolhasBeenFlipped: bool}
(the Card type is just to show you the format of the allCards and cardsPicked array. I'm using JavaScript so it's not part of the code)
When I log the cardsPicked array (on a time it doesn't have undefined values), it logs fine. But whenever it has undefined values, I get a "-1" index inside the console (I'm using Firefox 123.0.1). It looks something like below:
Array() [ {...}, {...}, undefined, {...}, {...}]
"-1": Object {cardName...}
0: Object {cardName...}
1: Object {cardName...}
2: Object {cardName...}
3: Object {cardName...}
4: Object {cardName...}
I don't get that "-1" object when the array doesn't have undefined elements
Any help is greatly appreciated! Thank you!
To use Array.prototype.filter here might be obvious. So to remove only undefined values we could call
var data = [42, 21, undefined, 50, 40, undefined, 9];
data = data.filter(function( element ) {
return element !== undefined;
});
If we want to filter out all the falsy values (such as 0 or null) we can use return !!element; instead.
But we can do it slighty more elegant, by just passing the Boolean constructor function, respectively the Number constructor function to .filter:
data = data.filter( Number );
That would do the job in this instance, to generally remove any falsy value, we would call
data = data.filter( Boolean );
Since the Boolean() constructor returns true on truthy values and false on any falsy value, this is a very neat option.
Inline using lambda
result.filter(item => item);
It's not php - you should use
var variable_name = new Array()
or even better
var variable_name = []
That's not how to declare variables as an empty array. You should be using:
var articleHTML = [];
See this previous question for reasoning of using this method instead of new Array()
.push appends it to the array, siblings[0] contains it because it's the first element in (formerly) empty array.
If you want to determine the key yourself, do
siblings = {};
siblings['key'] = 'something';
Otherwise loop through the array if you want to access each element
for ( var l = siblings.length, i = 0; i<l; ++i ) {
alert( siblings[i] )
}
Note: arrays are objects so I could've set siblings['key'] = 'something'; on the array, but that's not preferred.
siblings is an array. You're pushing the value 'uin_'+rand onto it, so the keys would then be 0. Instead, you'd want to create an object.
var siblings={};
var rand=+new Date();
siblings['uin_'+rand]="something";
alert(siblings['uin_' + rand]);