17

I come from Java. I studied the Swift documentation and understood most of the concepts.

What I now looking for is an equivalent to the Java indexOf and lastIndexOf methods to finding positions of substring in a string.

I already found a solution with rangeOfString and using the startIndex property. That looks helpful for me to define the indexOf method.

But I think that rangeOfString only starts searching from the beginning of a string. Is this correct? And if so, how can I search in reverse direction (from end to start of the string)?

What I mean is to have f.e. the string "hello world" and if I start searching for "l" then I want to find the letter at position 9 and not at position 2.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
altralaser
  • 2,035
  • 5
  • 36
  • 55

4 Answers4

26

In Swift 3

Java indexOf equivalent:

var index1 = string1.index(string1.endIndex, offsetBy: -4)

Java lastIndexOf equivalent:

 var index2 = string2.range(of: ".", options: .backwards)?.lowerBound
Danyl
  • 2,012
  • 3
  • 19
  • 40
  • 7
    Why do you have `offsetBy: -4` for the indexOf ? – John Difool Feb 25 '18 at 03:23
  • @Laurent indexOf has an optional fromIndex: https://beginnersbook.com/2013/12/java-string-indexof-method-example/ – Patrick Aug 08 '19 at 11:51
  • In Swift 5 the "lastIndexOf" code returns a `String.Index`, not an `Int` (like in Java). You could as well just do `mystring.lastIndex(of: ".")`, which is shorter and also returns a `String.Index`. The problem is that there doesn't seem to be an easy way to convert that into a proper `Int` you can work with. – Neph Mar 03 '21 at 10:15
8
extension String {
    func indexOf(_ input: String,
                 options: String.CompareOptions = .literal) -> String.Index? {
        return self.range(of: input, options: options)?.lowerBound
    }

    func lastIndexOf(_ input: String) -> String.Index? {
        return indexOf(input, options: .backwards)
    }
}

"hello world".indexOf("l") // 2
"hello world".lastIndexOf("l") // 9
Vladimir Kofman
  • 1,983
  • 21
  • 21
7

If you want the returned value to be an Int:

extension String {

    func lastIndex(of string: String) -> Int? {
        guard let index = range(of: string, options: .backwards) else { return nil }
        return self.distance(from: self.startIndex, to: index.lowerBound)
    }
}
Aviv Ben Shabat
  • 1,073
  • 2
  • 13
  • 33
0

There is a built in swift function for finding the index of last occurrence of a character. The function signature is below

public func lastIndex(of element: Character) -> String.Index?{}

We can get the index for a character like below:

let url = "http://www.google.com/abc"
guard let lastIndexOfChar = url.lastIndex(of: "/") else { return nil }
let startIndex = url.index(lastIndexOfChar, offsetBy:1)
let substring = url[startIndex..<url.endIndex] // prints "abc"
paddy
  • 47
  • 7