Как создать диапазон в Swift?


в Objective-c мы создаем диапазон с помощью NSRange

NSRange range;

Итак, как создать диапазон в Swift?

9 83

9 ответов:

обновлено для Swift 4

Swift диапазоны являются более сложными, чем NSRange, и они не стали легче в Swift 3. Если вы хотите попытаться понять причины некоторых из этих сложностей, прочитайте этой и этой. Я просто покажу вам, как их создавать и когда вы можете их использовать.

Закрытые Диапазоны: a...b

этой оператор диапазона создает быстрый диапазон, который включает в себя оба элемента aи элемент b, даже если b - это максимально возможное значение для типа (например,Int.max). Существует два различных типа закрытых диапазонов:ClosedRange и CountableClosedRange.

1. ClosedRange

элементы всех диапазонов в Swift сопоставимы (т. е. они соответствуют сопоставимых протокола). Это позволяет получить доступ к элементам в диапазоне из коллекции. Вот пример:

let myRange: ClosedRange = 1...3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

однако, a ClosedRange не является счетным (т. е. не соответствует протоколу последовательности). Это означает, что вы не можете перебирать элементы с помощью for петли. Для этого вам нужно CountableClosedRange.

2. CountableClosedRange

это похоже на последний, за исключением того, что теперь диапазон также может быть повторен.

let myRange: CountableClosedRange = 1...3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

for index in myRange {
    print(myArray[index])
}

Полуоткрытые Диапазоны: a..<b

этот оператор диапазона включает в себя элемент a но не элемент b. Как и выше, существует два различных типа полуоткрытых диапазонов:Range и CountableRange.

1. Range

С ClosedRange, вы можете получить доступ к элементам коллекции с Range. Пример:

let myRange: Range = 1..<3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

опять же, вы не можете перебирать Range потому что это только сопоставимо, а не шагает.

2. CountableRange

A CountableRange позволяет итерации.

let myRange: CountableRange = 1..<3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

for index in myRange {
    print(myArray[index])
}

NSRange

вы можете (должны) по-прежнему использовать NSRange время от времени в Swift (при создании отнести строки, например), поэтому полезно знать, как сделать один.

let myNSRange = NSRange(location: 3, length: 2)

обратите внимание, что это расположение и длина, а не начальный индекс и конечный индекс. Пример здесь похож по смыслу на Swift range 3..<5. Однако, поскольку типы различны, они не являются взаимозаменяемыми.

диапазоны со строки

The ... и

Xcode 8 beta 2 * Swift 3

let myString = "Hello World"
let myRange = myString.startIndex..<myString.index(myString.startIndex, offsetBy: 5)
let mySubString = myString.substring(with: myRange)   // Hello

Xcode 7 * Swift 2.0

let myString = "Hello World"
let myRange = Range<String.Index>(start: myString.startIndex, end: myString.startIndex.advancedBy(5))

let mySubString = myString.substringWithRange(myRange)   // Hello

или просто

let myString = "Hello World"
let myRange = myString.startIndex..<myString.startIndex.advancedBy(5)
let mySubString = myString.substringWithRange(myRange)   // Hello

(1..

возвращает...

использовать такой

var start = str.startIndex // Start at the string's start index
var end = advance(str.startIndex, 5) // Take start index and advance 5 characters forward
var range: Range<String.Index> = Range<String.Index>(start: start,end: end)

let firstFiveDigit =  str.substringWithRange(range)

print(firstFiveDigit)

выход : Привет

Я нахожу удивительным, что даже в Swift 4 до сих пор нет простого собственного способа выразить диапазон строк с помощью Int. Единственные строковые методы, которые позволяют вам предоставить Int как способ получения подстроки по диапазону, - это prefix и suffix.

полезно иметь под рукой некоторые утилиты преобразования, так что мы можем говорить, как NSRange при разговоре со строкой. Вот утилита, которая принимает местоположение и длину, как и NSRange, и возвращает a Range<String.Index>:

func range(_ start:Int, _ length:Int) -> Range<String.Index> {
    let i = self.index(start >= 0 ? self.startIndex : self.endIndex,
        offsetBy: start)
    let j = self.index(i, offsetBy: length)
    return i..<j
}

например, "hello".range(0,1)" - это Range<String.Index> обнимая первый символ "hello". В качестве бонуса, я разрешил отрицательные места:"hello".range(-1,1)" - это Range<String.Index> обнимая последний символ "hello".

полезно также преобразовать Range<String.Index> к NSRange, для тех моментов, когда вам нужно поговорить с Cocoa (например, при работе с диапазонами атрибутов NSAttributedString). Swift 4 предоставляет собственный способ сделать это:

let nsrange = NSRange(range, in:s) // where s is the string

мы таким образом, можно написать еще одну утилиту, где мы переходим непосредственно из строкового местоположения и длины в NSRange:

extension String {
    func nsRange(_ start:Int, _ length:Int) -> NSRange {
        return NSRange(self.range(start,length), in:self)
    }
}

Если кто-то хочет создать объект NSRange можно создать как:

let range: NSRange = NSRange.init(location: 0, length: 5)

это создаст диапазон с позицией 0 и длиной 5

Я создал следующее расширение:

extension String {
    func substring(from from:Int, to:Int) -> String? {
        if from<to && from>=0 && to<self.characters.count {
            let rng = self.startIndex.advancedBy(from)..<self.startIndex.advancedBy(to)
            return self.substringWithRange(rng)
        } else {
            return nil
        }
    }
}

пример использования:

print("abcde".substring(from: 1, to: 10)) //nil
print("abcde".substring(from: 2, to: 4))  //Optional("cd")
print("abcde".substring(from: 1, to: 0))  //nil
print("abcde".substring(from: 1, to: 1))  //nil
print("abcde".substring(from: -1, to: 1)) //nil
func replace(input: String, start: Int,lenght: Int, newChar: Character) -> String {
var chars = Array(input.characters)

for i in start...lenght {
    guard i < input.characters.count else{
        break
    }
    chars[i] = newChar
}
return String(chars)

}

Вы можете использовать такой

let nsRange = NSRange(location: someInt, length: someInt)

а в

let myNSString = bigTOTPCode as NSString //12345678
let firstDigit = myNSString.substringWithRange(NSRange(location: 0, length: 1)) //1
let secondDigit = myNSString.substringWithRange(NSRange(location: 1, length: 1)) //2
let thirdDigit = myNSString.substringWithRange(NSRange(location: 2, length: 4)) //3456