DEV Community

loading...
Cover image for Introducing `findLast` and `findLastIndex`

Introducing `findLast` and `findLastIndex`

Laurie
Software dev at Netflix | DC techie | Conference speaker | egghead Instructor | TC39 Educators Committee | Girls Who Code Facilitator | Board game geek | @laurieontech on twitter
Originally published at laurieontech.com ・2 min read

I'm back with another introduction to JavaScript syntax! Currently in Stage 2, we're going to talk about findLast and findLastIndex.

Array.prototype.find

Let's start by talking about a sometimes used array function called find. It's a nice utility method that helps you find the first element in an array that meets the given criteria.

const arr = [
  { letter: 'a', integer: 1 },
  { letter: 'c', integer: 2 },
  { letter: 'c', integer: 3 },
  { letter: 'd', integer: 4 },
]
arr.find(el => el.letter === 'c') // { letter: 'c', integer: 2 },
Enter fullscreen mode Exit fullscreen mode

There is a complimentary function called findIndex.

const arr = [
  { letter: 'a', integer: 1 },
  { letter: 'c', integer: 2 },
  { letter: 'c', integer: 3 },
  { letter: 'd', integer: 4 },
]
arr.findIndex(el => el.letter === 'c') // 1
Enter fullscreen mode Exit fullscreen mode

You can imagine why someone might want to do this. If you're looking for an element that matches what you want, but you only need one, this is super useful and very performant.

But it's only first

While find is great, it always gets the first element that meets the criteria. What happens if you're continuously pushing elements onto your array and you want the "most recent" element that meets the criteria. This would be the element closest to the end.

You could do this in a few ways. The one that comes to mind for me is to reverse the array and then use find. But this isn't performant for large arrays, it requires more steps than it should, and it doesn't work well if there aren't any matching elements in the array.

Enter findLast. It's the mirror function to find, but it works from the end of the array.

const arr = [
  { letter: 'a', integer: 1 },
  { letter: 'c', integer: 2 },
  { letter: 'c', integer: 3 },
  { letter: 'd', integer: 4 },
]
arr.findLast(el => el.letter === 'c') // { key: 'c', integer: 3 }
Enter fullscreen mode Exit fullscreen mode

There is also a matching findLastIndex.

const arr = [
  { letter: 'a', integer: 1 },
  { letter: 'c', integer: 2 },
  { letter: 'c', integer: 3 },
  { letter: 'd', integer: 4 },
]
arr.findLastIndex(el => el.letter === 'c') // 2
Enter fullscreen mode Exit fullscreen mode

Note that if it can't find an element that matches the criteria, it will return -1.

What do you think?

In my mind we can never have too many array utility methods! Whether I need them or not. But how about you?

If you're interested in learning more, check out the proposal.

Discussion (11)

Collapse
nicozerpa profile image
Nico Zerpa (he/him)

I had to find the last occurrence in an array just minutes ago, lol
I agree with you, there's never too many array utility methods.

The one that comes to mind for me is to reverse the array and then use find. But this isn't performant for large arrays, it requires more steps than it should, and it doesn't work well if there aren't any matching elements in the array.

Exactly. Also, if you reverse the array using Array.prototype.reverse, you're modifiying the original array. I've learned that the hard way.

Collapse
link2twenty profile image
Andrew Bone
const findLastIndex = (array, comparitor) => {
  for (let i = array.length - 1; i >= 0; i--)
    if (comparitor(array[i])) return i;

  return -1;
}

findLastIndex(arr, el => el.letter === 'c')
Enter fullscreen mode Exit fullscreen mode

It saves having to write a function to go through them for you. I generally think anytime the browser takes on some of complication I might have to face, that can only be a good thing.

Collapse
darkwiiplayer profile image
DarkWiiPlayer

I generally think anytime the browser takes on some of complication I might have to face, that can only be a good thing.

Well, yes, but only up to a certain point; if there was too much clutter, it'd get more and more difficult to find the right method for a task and in the end people would just end up writing their own methods anyway.

Also JS has a habit of cramming too much functionality into one feature, but harms the feature in the process, like is the case with map which completely messes up variadic functions because for some reason it passes along more arguments than it needs to.

Collapse
lapstjup profile image
Lakshya Thakur

I think a deep cloning utility method would be 🔥 as well. For learning purposes, I implemented my own here.

Don’t know if we have on going proposal for the same though.

Collapse
nickytonline profile image
Nick Taylor (he/him)

Yes! It’s like my dream came true when I asked for it in your other post lol.

I've used var last = arr[arr.length - 1] in the past, but now with destructuring, I typically do const [, last] = someArray.

I'm not sure I'd use at aside from getting the last item in an array since currently I can do
e.g. someArray[1] which is less typing than someArray.at(1) for elements that are not the last item. I probably would have opted for an Array.prototype.last.

Maybe there are use cases for it that I'm missing like composing a bunch of functions.

Not everyone is seeing my addendum to this comment so here it is

Just an update to my initial comment as I typed it out pretty quickly yesterday. const [, last] = someArray will work if the array was only two items. For example, if it's 4 items, this won't work. You'll end up with this.

const a = [1,2,3,4];
const [,last] = a;

console.log(last); // a === 2
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode


Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode

Enter fullscreen mode Exit fullscreen mode

If I wanted to get the last element in the above array, I'd have to do this.

const a = [1,2,3,4];
const [, , ,last] = a;

console.log(last); // a === 2
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode


Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode

Enter fullscreen mode Exit fullscreen mode
</div>
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode

Enter fullscreen mode Exit fullscreen mode


</div>
Enter fullscreen mode Exit fullscreen mode

Collapse
laurieontech profile image
Laurie Author

That post is far too noisy. I lost track of comments many days ago.

Collapse
jfbrennan profile image
Jordan Brennan

Maybe TC39 should take all that "noise" as a hint that dumping arr.last() is a disservice to the community 🤗

Collapse
roytouw7 profile image
roytouw7

I like it and I agree.

Collapse
jfbrennan profile image
Jordan Brennan

Nice! And thanks for highlighting these on dev.to

Collapse
sanidz profile image
sanidz

totaly unnecessary,

arr.reverse().find does the trick...

Collapse
laurieontech profile image
Laurie Author

It also mutates the array