24

Suppose I am a user script developer and I don't have control over the on-page javascript. The page creates arrays with random lengths, filling them with random values (including falsy ones, such as undefined). Not every element has to be assigned a value, so there may be empty slots.

A simplified example (Firefox console):

var arr = new Array(3);
arr[0] = null;
arr[1] = undefined;
console.log(arr);               \\ Array [ null, undefined, <1 empty slot> ]
console.log(arr[1]);            \\ undefined
console.log(arr[2]);            \\ undefined
console.log(arr[1] === arr[2]); \\ true
console.log(typeof arr[1]);     \\ undefined
console.log(typeof arr[2]);     \\ undefined

As we can see, Firefox displays undefined and empty slots differently, whereas for javascript they seem to be identical.

Now suppose I want to clean such an array, removing all empty slots but leaving undefined elements intact. How do I do that?

1
  • 1
    what means empty slots? do you want a new array? Commented Nov 22, 2016 at 22:02

2 Answers 2

30

You can use the in operator to check if the array has a key. It will return false for empty slots, but true for slots with values, including the value undefined:

var arr = new Array(3);
arr[0] = null;
arr[1] = undefined;

1 in arr; // true
2 in arr; // false

Note that you can't distinguish between empty slots and slots past the end of the array using that, but if you know the length of the array, then you already know that 3 isn't part of it, so you don't need to test 3 in arr.

You can also filter out the empty slots like this:

arr = arr.filter( ( _, i ) => i in arr );
Sign up to request clarification or add additional context in comments.

3 Comments

Wow this is clever.
@paul what if empty slot is in middle of array [null, , undefined]?
@Shivam That doesn't change anything about this answer except the indexes to check: 1 in arr will be false, but 0 in arr and 2 in arr will be true.
4

You could use Array#forEach, which omits sparse elements.

var arr = new Array(3);
arr[0] = null;
arr[1] = undefined;
console.log(arr); 

var withoutSparse = [];

arr.forEach(function (a, i) {
    console.log(i);
    withoutSparse.push(a);
});
console.log(withoutSparse);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

The same with Array.map. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.