2016-12-07 3 views
0

Я хочу найти первое вхождение строки, начинающейся с данного индекса.найти первое вхождение строки, начинающейся с заданного индекса

основе this answer Я создал следующие функции:

func index(of string: String, from startIndex: String.Index? = nil, options: String.CompareOptions = .literal) -> String.Index? { 
    if let startIndex = startIndex { 
     return range(of: string, options: options, range: startIndex ..< string.endIndex, locale: nil)?.lowerBound 
    } else { 
     return range(of: string, options: options, range: nil, locale: nil)?.lowerBound 
    } 
} 

, к сожалению, часть с индексом не работает.

Например следующий код возвращает nil вместо 3:

let str = "test" 
str.index(of: "t", from: str.index(str.startIndex, offsetBy: 1)) 
+1

Вы ограничив поиск неправильного диапазона. 'string.endIndex' должен быть' self.endIndex' (или просто 'endIndex'). –

+0

Как всегда, вы правы @MartinR. Теперь это работает, спасибо! – Daniel

ответ

2

Вы ограничив поиск неправильного диапазона. string.endIndex должно быть self.endIndex (или только endIndex).

Дальнейшие замечания:

  • range: nil и locale: nil могут быть исключены, поскольку эти параметры имеют значения по умолчанию.

  • String.Index может быть сокращен до Index внутри метода расширения String , аналогично для String.CompareOptions.

  • Я бы не стал называть необязательный параметр startIndex как вызывает путаницы с startIndex свойством String.

Собираем все вместе:

extension String { 
    func index(of string: String, from startPos: Index? = nil, options: CompareOptions = .literal) -> Index? { 
     if let startPos = startPos { 
      return range(of: string, options: options, range: startPos ..< endIndex)?.lowerBound 
     } else { 
      return range(of: string, options: options)?.lowerBound 
     } 
    } 
} 

или в качестве альтернативы

extension String { 
    func index(of string: String, from startPos: Index? = nil, options: CompareOptions = .literal) -> Index? { 
     let startPos = startPos ?? startIndex 
     return range(of: string, options: options, range: startPos ..< endIndex)?.lowerBound 
    } 
}