gpt4 book ai didi

swift - 如何在 Swift 中创建范围?

转载 作者:IT王子 更新时间:2023-10-29 04:56:40 26 4
gpt4 key购买 nike

在 Objective-c 中,我们使用 NSRange 创建范围

NSRange range;

那么如何在 Swift 中创建范围呢?

最佳答案

为 Swift 4 更新

Swift 范围比 NSRange 更复杂,并且它们在 Swift 3 中并没有变得更容易。如果你想尝试理解这种复杂性背后的原因,请阅读 thisthis .我只会向您展示如何创建它们以及何时可以使用它们。

封闭范围:a...b
range operator创建一个包含两个元素 a 的 Swift 范围和元素 b ,即使 b是类型的最大可能值(如 Int.max )。有两种不同类型的封闭范围:ClosedRangeCountableClosedRange .

1. ClosedRange
Swift 中所有范围的元素都是可比较的(即,它们符合 Comparable 协议(protocol))。这允许您访问集合中范围内的元素。下面是一个例子:

let myRange: ClosedRange = 1...3

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

然而,一个 ClosedRange不可数(即不符合 Sequence 协议(protocol))。这意味着你不能用 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 .像上面一样,有两种不同类型的半开范围: RangeCountableRange .

1. Range
ClosedRange 一样,您可以使用 Range 访问集合的元素.示例:
let myRange: Range = 1..<3

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

但是,同样,您不能迭代 Range因为它只有可比性,没有可比性。

2. CountableRange
一个 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 中(例如,在制作 attributed strings 时),所以知道如何制作一个很有帮助。
let myNSRange = NSRange(location: 3, length: 2)

请注意,这是位置和长度,而不是开始索引和结束索引。此处的示例与 Swift 范围 3..<5 的含义相似。 .但是,由于类型不同,它们不能互换。

带字符串的范围
.....<范围运算符是创建范围的一种简写方式。例如:
let myRange = 1..<3

创建相同范围的长期方法是
let myRange = CountableRange<Int>(uncheckedBounds: (lower: 1, upper: 3)) // 1..<3

可以看到这里的索引类型是 Int .这不适用于 String ,不过,因为字符串是由字符组成的,并非所有字符的大小都相同。 (阅读 this 了解更多信息。)例如,像 😀 这样的表情符号比字母“b”占用更多的空间。

NSRange 问题

尝试尝试 NSRange和一个 NSString用表情符号,你就会明白我的意思。头痛。
let myNSRange = NSRange(location: 1, length: 3)

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

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

笑脸需要两个 UTF-16 代码单元来存储,所以它给出了不包括“d”的意外结果。

swift 解决方案

因此,对于 Swift 字符串,您可以使用 Range<String.Index> ,不是 Range<Int> .字符串索引是基于特定字符串计算的,因此它知道是否有任何表情符号或扩展字素簇。

示例
var myString = "abcde"
let start = myString.index(myString.startIndex, offsetBy: 1)
let end = myString.index(myString.startIndex, offsetBy: 4)
let myRange = start..<end
myString[myRange] // "bcd"

myString = "a😀cde"
let start2 = myString.index(myString.startIndex, offsetBy: 1)
let end2 = myString.index(myString.startIndex, offsetBy: 4)
let myRange2 = start2..<end2
myString[myRange2] // "😀cd"

单边范围: a......b..<b
在 Swift 4 中,事情被简化了一点。每当可以推断出范围的起点或终点时,您都​​可以将其省略。

国际

您可以使用单边整数范围来迭代集合。以下是来自 documentation 的一些示例.
// iterate from index 2 to the end of the array
for name in names[2...] {
print(name)
}

// iterate from the beginning of the array to index 2
for name in names[...2] {
print(name)
}

// iterate from the beginning of the array up to but not including index 2
for name in names[..<2] {
print(name)
}

// the range from negative infinity to 5. You can't iterate forward
// over this because the starting point in unknown.
let range = ...5
range.contains(7) // false
range.contains(4) // true
range.contains(-1) // true

// You can iterate over this but it will be an infinate loop
// so you have to break out at some point.
let range = 5...

字符串

这也适用于字符串范围。如果您使用 str.startIndex 制作范围或 str.endIndex一方面,您可以将其关闭。编译器会推断出来。

给定的
var str = "Hello, playground"
let index = str.index(str.startIndex, offsetBy: 5)

let myRange = ..<index // Hello

您可以使用 ... 从索引转到 str.endIndex
var str = "Hello, playground"
let index = str.index(str.endIndex, offsetBy: -10)
let myRange = index... // playground

另见:
  • How does String.Index work in Swift
  • How does String substring work in Swift

  • 备注
  • 您不能在不同的字符串上使用通过一个字符串创建的范围。
  • 如您所见,字符串范围在 Swift 中很麻烦,但它们确实可以更好地处理表情符号和其他 Unicode 标量。

  • 进修
  • String Range examples
  • Range Operator documentation
  • Strings and Characters documentation
  • 关于swift - 如何在 Swift 中创建范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30093688/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com