Reputation: 24116
Consider the following:
var answers = [];
answers[71] = {
field: 'value'
};
answers[31] = {
field: 'value'
};
console.log(answers);
This outputs the length of the array as 72 but I was expecting it to return 2. Here's the output of the script from chrome console:
Any ideas why this is?
Upvotes: 18
Views: 46623
Reputation: 14768
You can count the actual number of keys using Object.keys(array).length
:
const answers = [];
answers[71] = {
field: 'value'
};
answers[31] = {
field: 'value'
};
console.log(Object.keys(answers).length); // prints 2
Upvotes: 39
Reputation:
Any ideas why this is?
Because that's how the language works.
From MDN:
The
length
property represents an unsigned, 32-bit integer that is always numerically greater than the highest index in the array.
From the spec:
Specifically, whenever an own property is added whose name is an array index, the value of the
length
property is changed, if necessary, to be one more than the numeric value of that array index;
Notice that it is not true that the length is always one greater than the index of the last populated item. In your case, if you did
answers[71] = {field: 'value'};
answers[31] = {field: 'value'};
The length would now be 72, but if you then did
delete answers[71];
the length would remain 72, and not be adjusted down to 32.
If your question was actually to find the actual number of populated slots in the array, see the other answers, or you could brute-force it, looping over all indexes up to the length and checking if a slot is populated using the in
operator:
let count = 0;
for (let i = 0; i < arr.length; i++) count += i in arr;
Upvotes: 2
Reputation: 2647
By defining index 71, you've told the array that it needs to hold at least 72 entries, and any that you don't explicitly define will hold a value of undefined
.
To find the number of actual elements, you can iterate through the array and check whether each element is undefined
or not, and count how many are not undefined
Upvotes: 3
Reputation: 115222
You can simply use Array#filter
method which doesn't iterate over deleted or undefined array elements.
answers.filter(function(v){ return true; }).length
var answers = [];
answers[71] = {
field: 'value'
};
answers[31] = {
field: 'value'
};
console.log(answers.filter(function(v) {
return true;
}).length);
Upvotes: 3
Reputation: 1451
Just use object instead of array and check
Object.keys(your_object_like_array).length
to get the amount.
Upvotes: 1
Reputation: 386578
You could count it with Array#forEach
or use Array#reduce
var answers = [], count = 0;
answers[71] = { field: 'value' };
answers[31] = { field: 'value' };
answers.forEach(_ => count++);
console.log(count);
console.log(answers.reduce(r => r + 1, 0));
Upvotes: 3