Один из способов сделать это - сначала отобразить строки в кортеж, содержащий индекс искомого текста в строке и саму строку. Затем выполните сортировку по индексу, затем сопоставьте кортежи со строками.
let array = ["Anand", "Ani", "Dan", "Eion", "Harsh", "Jocab", "Roshan", "Stewart"]
let searchText = "R"
// compactMap acts as a filter, removing the strings where string.index(of: searchText, options: [.caseInsensitive]) returns nil
let result = array.compactMap { string in string.index(of: searchText, options: [.caseInsensitive]).map { ($0, string) } }
.sorted { $0.0 < $1.0 }.map { $0.1 }
Метод index(of:options:)
взят из этого ответа здесь .
Для Swift 4.x:
extension StringProtocol where Index == String.Index {
func index(of string: Self, options: String.CompareOptions = []) -> Index? {
return range(of: string, options: options)?.lowerBound
}
func endIndex(of string: Self, options: String.CompareOptions = []) -> Index? {
return range(of: string, options: options)?.upperBound
}
func indexes(of string: Self, options: String.CompareOptions = []) -> [Index] {
var result: [Index] = []
var startIndex = self.startIndex
while startIndex < endIndex,
let range = self[startIndex...].range(of: string, options: options) {
result.append(range.lowerBound)
startIndex = range.lowerBound < range.upperBound ? range.upperBound :
index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
}
return result
}
func ranges(of string: Self, options: String.CompareOptions = []) -> [Range<Index>] {
var result: [Range<Index>] = []
var startIndex = self.startIndex
while startIndex < endIndex,
let range = self[startIndex...].range(of: string, options: options) {
result.append(range)
startIndex = range.lowerBound < range.upperBound ? range.upperBound :
index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
}
return result
}
}