18

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:

enter image description here

Any ideas why this is?

5
  • 3
    Since you were defined index 71 which creates array of length 72 and remaining elements would be undefined Commented Sep 8, 2016 at 18:07
  • the real script i am working on will need to work with arbitrary indexes in the array as per example. How would I go about counting the actual number of elements in the array? Commented Sep 8, 2016 at 18:08
  • answers.filter(function(v){return true;}).length; , filter wouldn't itertate over undefined or deleted elements Commented Sep 8, 2016 at 18:10
  • 2
    What use case do you need sparse arrays for? Commented Sep 8, 2016 at 18:11
  • 1
    @Latheesan: Have you considered using an object (var answers = {};) instead of an array? Commented Sep 8, 2016 at 18:56

6 Answers 6

39

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

Sign up to request clarification or add additional context in comments.

3 Comments

This works fine for what the OP is looking for, but fails in the case that the array has non-integer properties.
@torazaburo Not from what I can tell: CodePen.
Right, my point is that the OP is presumably looking for an answer of 2 in that case, but gets 3 instead.
3

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));

Comments

3

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);

Comments

3

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

4 Comments

elements can have undefined as value.
Actually, they are not "populated" with undefined. They are simply undefined, and there is a difference.
@torazaburo Better wording?
I would prefer to say "any that you don't explicitly define will be left undefined". As Nina points out, there is a subtle difference between the array slot HOLDING a value of undefined, and it simply BEING undefined.
2

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;

Comments

1

Just use object instead of array and check

Object.keys(your_object_like_array).length

to get the amount.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.