Reputation: 12880
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.
Upvotes: 8
Views: 8154
Reputation: 1
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));
Upvotes: 0
Reputation: 411
Try this:
array.length - array.slice(0).reverse().findIndex(function (el) { return el }) - 1;
Upvotes: 0
Reputation: 197
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.
Upvotes: 0
Reputation: 803
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.
Upvotes: 4
Reputation: 386560
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]);
Upvotes: 9