0

Going through Swift algorithms including the brute force string search i.e.: https://github.com/raywenderlich/swift-algorithm-club/tree/master/Brute-Force%20String%20Search

The output is said to be 7

Now actually the output is (String.Index?) - and although I can subscript with that I want to actually see the value - 7.

The code is

extension String {
  func indexOf(_ pattern: String) -> String.Index? {
    for i in self.characters.indices {
        var j = i
        var found = true
        for p in pattern.characters.indices{
            if j == self.characters.endIndex || self[j] != pattern[p] {
                found = false
                break
            } else {
                j = self.characters.index(after: j)
            }
        }
        if found {
            return i
        }
    }
    return nil
  }
}

I've looked at converting String.Index to range in the documentation and here: Convert String.Index to Int or Range<String.Index> to NSRange but the answer to that question is old and does not present an answer (if such an answer exists) for Swift 4.

Distance to also does not work as in:

let s = "Hello, World"
let res = ( s.indexOf("World") )
let index: Int = s.startIndex.distance(to: res)
print (s[res!])

and the existing OffsetIndexableCollection does not even compile

so how can I convert

s.indexOf("World") 

to "7" where s is "Hello, World"

WishIHadThreeGuns
  • 1,225
  • 3
  • 17
  • 37
  • 2
    It is NOT a duplicate, I even linked to one of the questions suggested that it is NOT a duplicate of because it does not answer the question as explained in detail in the question. The answer below DOES answer the question, and does not feature in the so called duplicates! Why don't people read the question before doing this? – WishIHadThreeGuns Feb 26 '19 at 03:22
  • and regarding your code trying to get the distance `let s = "Hello, World" if let res = s.indexOf("World") { let distance = s.distance(from: s.startIndex, to: res) print(s[res...]) // "World\n" print(distance) // 7 }` – Leo Dabus Feb 26 '19 at 03:45

1 Answers1

0

Try this out:

s.indexOf("World").encodedOffset ?? -1
alanpaivaa
  • 1,959
  • 1
  • 14
  • 23
  • 1
    Returning magical numbers like -1 instead of nil in Swift it is a very bad design choice. – Leo Dabus Feb 26 '19 at 03:32
  • `encodedOffset` is going to be deprecated (https://github.com/apple/swift-evolution/blob/master/proposals/0241-string-index-explicit-encoding-offset.md) and is easily to misuse. As an example, `"".indexOf("")!.encodedOffset` returns **2** and not 1, as one would expect. – Martin R Feb 26 '19 at 05:59
  • @LeoDabus that is not in the scope of the question. Just wanted to mimic the behavior that is common in other languages. – alanpaivaa Feb 26 '19 at 12:07
  • @MartinR yeah, I got it. The reason is most likely because the characters have different lengths. However, that solution can still be useful depending on the context of the problem. Thanks for pointing it out! – alanpaivaa Feb 26 '19 at 12:13
  • downvoted because encodedOffset is now deprecated (Feb 2022) https://github.com/apple/swift-evolution/blob/master/proposals/0241-string-index-explicit-encoding-offset.md and https://www.swift.org/blog/utf8-string/ – Andy Dent Feb 25 '22 at 15:24