6

The function index of an Swift array returns the first element based on the condition inside the where clause. Is there a way to get the last element with this condition?

For example, I want something like this (I know there is no function called lastIndex. This function or similar is what I'm searching for):

let array = [1, 2, 3, 4, 5, 3, 6]

let indexOfLastElementEquals3 = array.lastIndex(where: { $0 == 3 })

print(indexOfLastElementEquals3) //5 (Optional)
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Roberto Sampaio
  • 531
  • 1
  • 5
  • 15

1 Answers1

9

lastIndex(where:) and related methods were added in Swift 4.2, see

In earlier Swift versions you can use index(where:) on the reversed view of the collection:

let array = [1, 2, 3, 4, 5, 3, 6]

if let revIndex = array.reversed().index(where: { $0 % 2 != 0 } ) {
    let indexOfLastOddElement = array.index(before: revIndex.base)
    print(indexOfLastOddElement) // 5
}

Or as a single expression:

let indexOfLastOddElement =  array.reversed().index(where: { $0 % 2 != 0 } )
    .map { array.index(before: $0.base) }

print(indexOfLastOddElement) // Optional(5)

revIndex.base returns the position after the position of revIndex in the underlying collection, that's why we have to “subtract” one from the index.

For arrays this can be simplified to

    let indexOfLastOddElement = revIndex.base - 1

but for collections with non-integer indices (like String) the above index(before:) methods is needed.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • @Sulthan: Yes, array indices are Int. For other collections (like String) you need index(before:) – Martin R May 10 '18 at 19:29
  • this targets odd value suppose he searches for an even , also there is no input , it's for this use case only – Shehata Gamal May 10 '18 at 19:37
  • @Sh_Khan: I am sorry, I do not understand what you mean. Is anything wrong here? – Martin R May 10 '18 at 19:39
  • suppose the search for index of last number 6 according to yours , then we have to change the `$0 % 2 != 0` to `$0 % 2 == 0` – Shehata Gamal May 10 '18 at 19:44
  • Another way of doing it would be to reverse the `indices`, e.g `array.indices.reversed().first(where: { array[$0] % 2 != 0 } )`. It means you have to do subscripting in the predicate, but on the other hand you don't have to adjust the returned index afterwards. – Hamish May 10 '18 at 22:10