For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/proposal-array-find-from-last.md.
  • English
  • Array find from last S4

    Proposal details
    Proposal overview

    This proposal adds findLast() and findLastIndex() methods to Array and TypedArray prototypes, allowing developers to find elements or their indices from the end of an array based on a condition. It addresses the need to iterate backward without mutation or complex index calculations, as required by workarounds like \[.arr\].reverse().find().

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    proposal-array-find-from-last

    Proposal for .findLast() and .findLastIndex() methods on array and typed array.

    Status

    This is a stage 4 proposal.

    Motivation

    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, %TypedArray%}.prototype.indexOf and {Array, %TypedArray%}.prototype.lastIndexOf to find an index of some value in the array.

    There is also {Array, %TypedArray%}.prototype.find and {Array, %TypedArray%}.prototype.findIndex to find 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:

    1. unnecessary mutation (by reverse).
    2. 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:

    1. complex index calculation

    So, perhaps we need something directly and effectively. In this proposal, they are {Array, %TypedArray%}.prototype.findLast and {Array, %TypedArray%}.prototype.findLastIndex.

    Scenarios

    • You know find from last may have better performance (The target element on the tail of the array, could append with push or concat 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.

    Core features

    Add {Array, %TypedArray%}.prototype.findLast and {Array, %TypedArray%}.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
    

    Slides

    Polyfill

    Proposer

    Champions:

    • @Kingwl (Wenlu Wang, KWL)
    • @DanielRosenwasser (Daniel Rosenwasser, DRR)