8

I have an array with defined and null values inside, like so :

var arr = [
  {...},
  null,
  null,
  {...},
  null
];

Is there any way for me to get the index of the last non-null element from this array? And I mean without having to loop through it entirely.

5 Answers 5

9

You could use a while loop and iterate from the end.

var array = [{ foo: 0 }, null, null, { bar: 42 }, null],
    index = array.length;
    
while (index-- && !array[index]);

console.log(index);
console.log(array[index]);

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

3 Comments

Already thought of that, I was asking for a way without a loop.
actually, you need a loop or some kind of loop like the build in arraymethods, but they loop only from the beginning, and reduceRight has no early exit.
So I guess there is no way of doing this without a loop then ... I was thinking there could be a .index for non-null elements. Thanks for trying anyway.
4

Filter the non-null get the value of last one, if you need the index get the index from the value. But requires the values to be unique.

// Last non-null value
const lastNonNull = arr.filter(x => x).pop();
// Index of last non-null
const indexOfLastNonNull = arr.indexOf(lastNonNull);

--Edit(1)

You may want to use reduce method of arrays, but before run reverse to make sure the sequence is from last to first. reduce works pretty fine, the first initial value is null then we check for result which is the first initial value so we pass on cur which is the first element of array, if it is truthy we return idx which is the index of array, if not we return null which will become the result in the next loop.

arr.reduce((result, cur, idx) => (result ? result : (cur ? idx : null)), null)

--Edit(2)

Or you may reverse the array and run indexOf like this:

arr.indexOf(null);

For reversing once you run arr.reverse() it'll reverse the content of array. No need to return anything.

6 Comments

I don't really get how your .filter() filters out the null elements. Can you elaborate a bit please?
Sure, to check if a variable is null or undefined you simple check it with a truthy and in JS it's like this if (variableX) ... in the sample I wrote it's the same case, the conditional is basically the variable itself, so if x is null or undefined it returns false, and won't be included in the return. Remember the fat arrow functions => is for this case to return the expression without writing the whole function.
To elaborate a bit more the filter fat arrow is equivalent of filter( function(x) { return x; } ).
filter visits every element of an array.
Thanks, I get it now. But as said, going through every element of my array would not be a good idea, it can contain up to 10 000 entries.
|
0
const reverse = arr => {
    let cpy = [...arr];
    cpy.reverse();
    return cpy;
};

const nonNullIndex = arr => {
    let res = arr.length - 1 - reverse(arr).findIndex(e => e !== null)

    return res === arr.length ? -1 : res;
};

This should work. The reverse function returns an array, as Array.prototype.reverse reverses it in-place, not returning anything.

The nonNullIndex function returns the last index where it isn't null. Since it reverses the array, you must subtract the index found from the length of the array. The subtraction of one is used so that it returns the right value (since arrays are indexed at 0).

If the result is equal to the length (meaning that findIndex returned -1), it returns -1, meaning there are no null values in the array. Otherwise, it returns the result.

Comments

0

Try this:

array.length - array.slice(0).reverse().findIndex(function (el) { return el }) - 1;

Comments

0

You can use the map function to iterate through the array, check the condition and return the index, then take the maximum index:

Math.max.apply(null, arr.map(function (v, i) { return v !== null && i; });

or

Math.max(...arr.map((v, i) => v !== null && i));

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.