Proposal for .findLast()
and .findLastIndex()
methods on array.
This proposal is a stage 1 proposal and waiting for feedback.
Finding an element in an array is a very common programming pattern.
The proposal has a major concerns: Semantical. Which means clearly representing the operation i want
.
And with the changes. There's a sugar here: Performance. Avoid obvious overhead. And may improve the constant factors in the time complexity. Even there's not an order of magnitude change. But it's may useful in some performance-sensitive scenarios. eg: React render function.
ECMAScript currently supports Array.prototype.indexOf
and Array.prototype.lastIndexOf
to find an index of some value
in the array.
There is also Array.prototype.find
and Array.prototype.findIndex
to find the an element or its index in the array that satisfies a provided condition.
However, the language does not provide a method to find an element from the last to the first of an array with a condition function.
[...[]].reverse().find()
is a workaround but there are two issues:
- unnecessary mutation (by reverse).
- unnecessary copy (to avoid mutation)
For .findIndex()
, you are required to perform additional steps after calling the method (re-calculate the index and handle the -1
) to calculate the result of [...arr].reverse().findIndex()
.
Therefore there is a third issue:
- complex index calculation
So, perhaps we need something directly and effectily. In this proposal, they are Array.prototype.findLast
and Array.prototype.findLastIndex
.
- You know find from last may have better performance (The target element on the tail of the array, could append with
push
orconcat
in a queue or stack, eg: recently matched time point in a timeline). - You care about the order of the elements (May have duplicate item in the array, eg: last odd in the list of numbers).
- Etc.
Add Array.prototype.findLast
and Array.prototype.findLastIndex
.
This would behave the same as Array.prototype.find and Array.prototype.findIndex but would iterate from the last to the first.
eg:
const array = [{ value: 1 }, { value: 2 }, { value: 3 }, { value: 4 }];
array.find(n => n.value % 2 === 1); // { value: 1 }
array.findIndex(n => n.value % 2 === 1); // 0
// ======== Before the proposal ===========
// find
[...array].reverse().find(n => n.value % 2 === 1); // { value: 3 }
// findIndex
array.length - 1 - [...array].reverse().findIndex(n => n.value % 2 === 1); // 2
array.length - 1 - [...array].reverse().findIndex(n => n.value === 42); // should be -1, but 4
// ======== In the proposal ===========
// find
array.findLast(n => n.value % 2 === 1); // { value: 3 }
// findIndex
array.findLastIndex(n => n.value % 2 === 1); // 2
array.findLastIndex(n => n.value === 42); // -1
- lodash.findLast
- lodash.findLastIndex
- ramda.findLast
- ramda.findLastIndex
- TypeScript internal findLast
- TypeScript internal findLastIndex
- @extra-array/find-right
Champions:
- @Kingwl (Wenlu Wang, KWL)
- @DanielRosenwasser (Daniel Rosenwasser, DRR)