Tất cả các ví dụ sau đây sử dụng
var str = "Hello, playground"
startIndex
và endIndex
startIndex
là chỉ số của ký tự đầu tiên
endIndex
được chỉ số sau ký tự cuối cùng.
Ví dụ
// character
str[str.startIndex] // H
str[str.endIndex] // error: after last character
// range
let range = str.startIndex..<str.endIndex
str[range] // "Hello, playground"
Với Swift 4 của one-sided ranges, phạm vi có thể được đơn giản hóa với một trong các hình thức sau đây.
let range = str.startIndex...
let range = ..<str.endIndex
Tôi sẽ sử dụng biểu mẫu đầy đủ trong các ví dụ sau để rõ ràng, nhưng vì mục đích dễ đọc, có thể bạn sẽ muốn sử dụng các phạm vi một chiều trong mã của mình.
after
Như trong: index(after: String.Index)
after
đề cập đến các chỉ số của nhân vật trực tiếp sau khi chỉ số nhất định.
Ví dụ
// character
let index = str.index(after: str.startIndex)
str[index] // "e"
// range
let range = str.index(after: str.startIndex)..<str.endIndex
str[range] // "ello, playground"
before
Như trong: index(before: String.Index)
before
đề cập đến các chỉ số của nhân vật trực tiếp trước khi chỉ số nhất định.
Ví dụ
// character
let index = str.index(before: str.endIndex)
str[index] // d
// range
let range = str.startIndex..<str.index(before: str.endIndex)
str[range] // Hello, playgroun
offsetBy
Như trong: index(String.Index, offsetBy: String.IndexDistance)
- Giá trị
offsetBy
thể là tích cực hay tiêu cực và bắt đầu từ chỉ số nhất định. Mặc dù thuộc loại String.IndexDistance
, bạn có thể cung cấp cho nó Int
.
Ví dụ
// character
let index = str.index(str.startIndex, offsetBy: 7)
str[index] // p
// range
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
str[range] // play
limitedBy
Như trong: index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
- Các
limitedBy
rất hữu ích cho việc bảo đảm rằng bù đắp không gây các chỉ số đi ra ngoài giới hạn. Nó là một chỉ số giới hạn. Vì có thể bù đắp vượt quá giới hạn, phương thức này trả về tùy chọn. Nó trả về nil
nếu chỉ mục nằm ngoài giới hạn.
Ví dụ
// character
if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
str[index] // p
}
Nếu bù đắp đã 77
thay vì 7
, sau đó báo cáo kết quả if
sẽ bị bỏ qua.
Tại sao String.Index cần?
Nó sẽ là nhiều dễ sử dụng chỉ mục Int
cho chuỗi. Lý do bạn phải tạo một String.Index
mới cho mỗi chuỗi là các ký tự trong Swift không phải là tất cả cùng độ dài dưới mui xe. Một ký tự Swift đơn có thể bao gồm một, hai hoặc thậm chí nhiều điểm mã Unicode hơn. Vì vậy, mỗi chuỗi duy nhất phải tính toán các chỉ mục của các ký tự của nó.
Có thể ẩn sự phức tạp này sau phần mở rộng chỉ mục Int, nhưng tôi không muốn làm như vậy. Nó là tốt để được nhắc nhở về những gì đang thực sự xảy ra.
Tại sao 'startIndex' được bất cứ điều gì khác hơn 0? –
@RoboRobok: Bởi vì Swift làm việc với các ký tự Unicode, được tạo thành từ "các cụm grapheme", Swift không sử dụng các số nguyên để biểu diễn các vị trí chỉ mục. Giả sử nhân vật đầu tiên của bạn là 'é'. Nó thực sự được tạo thành từ biểu thức Unicode '' '' '' '' '' '' ''. Nếu bạn đã sử dụng chỉ mục bằng 0, bạn sẽ nhận được ký tự 'e' hoặc dấu trọng âm (" mộ "), không phải toàn bộ cụm tạo thành' é'. Sử dụng 'startIndex' đảm bảo bạn sẽ nhận được toàn bộ cụm grapheme cho bất kỳ ký tự nào. – leanne
Trong Swift 4.0, mỗi ký tự Unicode được tính bằng 1. Ví dụ: "" .count // Bây giờ: 1, Trước: 2 – selva