Reputation: 1552
JavaScript has array methods like indexOf
and find
for getting the first element in the array that matches the criteria. The counterpart to indexOf
would be lastIndexOf
, which searches starting from the end of the array instead. I'm wondering now if there is a counterpart to find
that starts from the end of the array, like a native implementation of Ramda's findLast
.
I would prefer to use neither array.slice().reverse().find()
due to performance costs nor a for
loop as it is verbose and not in the spirit of functional programming
Upvotes: 1
Views: 2159
Reputation: 56925
You can use reduceRight
, which is in the spirit of functional programming. However, it's not as easy (but possible) to return early upon finding a match as it is in a for
loop:
const lastIndexOf = (needle, haystack) =>
haystack.reduceRight((a, e, i) =>
a >= 0 ? a : e === needle ? i : -1
, -1)
;
const arr = [1,4,3,5,5,4,5];
console.log(lastIndexOf(4, arr));
console.log(lastIndexOf(2, arr));
There's also recursion, which has similar efficiency problems (stack frame overhead, no instantaneous early return, having to write a helper or extra conditionals, you'll blow the stack if the array is large...):
const lastIndexOf = (needle, haystack, idx) =>
lastIndexOfHelper(needle, haystack, haystack.length - 1)
;
const lastIndexOfHelper = (needle, haystack, idx) =>
idx < 0 || haystack[idx] === needle ?
idx : lastIndexOfHelper(needle, haystack, idx - 1)
;
const arr = [1,4,3,5,5,4,5];
console.log(lastIndexOf(4, arr));
console.log(lastIndexOf(2, arr));
Upvotes: 2
Reputation: 188
Lodash has a _.findLastIndex() method which interates over a collection from right to left. https://lodash.com/docs/4.17.10#findLastIndex
Not sure as to its performance though
Upvotes: 2
Reputation: 138267
No there is not, but you can polyfill it easily:
Array.prototype.findLast = function(fn) {
for(let i = this.length - 1; i >= 0; i--)
if(fn( this[i], i, this )) return this[i];
return null;
};
console.log([5,4,3,2,1].findLast(el => el > 3));
Upvotes: 2