Swift中Range的使用


相比OC中的NSRange,在Swift中使用Range是一個比較麻煩的事情,猶記得第一個使用,感覺寫法很復雜,這里簡單介紹下它的用法。

Close Ragne: a...b

這種操作創建了一個包括a和b的區間,有兩種不同的閉區間,CloseRange和CountableClosedRange

  • CloseRange

在Swift中所有Ranges中的元素都是可比的,遵循Comparable協議,這讓我們可以獲取集合中任意區間的元素

let myRange: ClosedRange = 1...3

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

它同CloseRange的區別就是它可以遍歷,遵循了Sequence協議

let myRange: CountableClosedRange = 1...3

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

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

Half-Open Ranges: a..<b

這是個左閉右開的區間,包括a但是不包括b。同樣也有兩種不同的類型:Range和CountableRange

  • Range

使用同ClosedRange類似

let myRange: Range = 1..<3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]
  • 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

在swift中同樣也是需要使用NSRange,因為通過不同的含義來創建的。

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

let myRange: Range = 3..<5

它是通過起始位置和長度來確定區間范圍,不同於Range通過起始和結束的位置。

Ranges with Strings

//Range
var myString = "abcde"
let start = myString.index(myString.startIndex, offsetBy: 1)
let end = myString.index(myString.startIndex, offsetBy: 4)
let myRange = start..<end
myString.substring(with: myRange) // "bcd"

//NSRange
let myNSRange = NSRange(location: 1, length: 3)

let myNSString: NSString = "abcde"
myNSString.substring(with: myNSRange) // "bcd"

可以看到NSRange比Range要簡潔多了,既然這樣,為什么蘋果還要想出個Range類型呢?

//Range
var myString = "a😀cde"
let start2 = myString.index(myString.startIndex, offsetBy: 1)
let end2 = myString.index(myString.startIndex, offsetBy: 4)
let myRange2 = start2..<end2
myString.substring(with: myRange2) // "😀cd"

//NSRange
let myNSString2: NSString = "a😀cde"
myNSString2.substring(with: myNSRange) // "😀c"    Where is the "d"!?

因為emoji笑臉占用了兩個UTF-16單元去存儲,所以和我們預期的就有所不同了。

Extension

可是要使用String時,Range寫法好復雜,該怎么辦?這里我們可以拓展String對象。

extension String {
    subscript(r: ClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start...end]
    }
    
    subscript(r: Range<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: r.lowerBound)
            let end = index(startIndex, offsetBy: r.upperBound)
            return self[start..<end]
        }
    }
}

//usage
"abcde"[1...3] = "bcd"
"abcde"[1..<3] = "bc"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM