比较String.Index值

时间:2014-08-04 00:25:29

标签: string macos swift

是否可以比较Swift中的两个String.Index值?我试图按字符处理字符串,有几次我需要检查我是否在字符串的末尾。我已经尝试过了

while (currentIndex < string.endIndex) {
    //do things...
    currentIndex = currentIndex.successor()
}

抱怨类型转换。然后,我尝试为<定义和重载:

@infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
    var ret = true //what goes here?
    return ret
}

哪个摆脱了编译错误,但我不知道如何正确比较lhsrhs。这是我应该使用String.Index的方式,还是有更好的方法来比较它们?

4 个答案:

答案 0 :(得分:0)

字符串索引支持=!=。字符串索引是一个不透明的类型,而不是整数,不能像整数那样进行比较。

使用:if (currentIndex != string.endIndex)

var currentIndex = string.startIndex
while (currentIndex != string.endIndex) {
    println("currentIndex: \(currentIndex)")
    currentIndex = currentIndex.successor()
}

答案 1 :(得分:0)

最简单的选项是distance()函数:

var string = "Hello World"
var currentIndex = string.startIndex

while (distance(currentIndex, string.endIndex) >= 0) {
  println("currentIndex: \(currentIndex)")
  currentIndex = currentIndex.successor()
}

注意distance()具有O(N)性能,因此请避免使用大字符串。但是,整个String类当前都不处理大字符串 - 如果性能很关键,您应该切换到CFString

使用运算符重载是一个坏主意,但作为一个学习练习,这就是你如何做到这一点:

var string = "Hello World"
var currentIndex = string.startIndex

@infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
  return distance(lhs, rhs) > 0
}

while (currentIndex < string.endIndex) {
  currentIndex = currentIndex.successor()
}

答案 2 :(得分:0)

我相信这个REPL / Playground示例应该说明你(和其他人)在使用String.Index概念时需要了解的内容。

// This will be our working example
let exampleString = "this is a string"

// And here we'll call successor a few times to get an index partway through the example
var someIndexInTheMiddle = exampleString.startIndex
for _ in 1...5 {
    someIndexInTheMiddle = someIndexInTheMiddle.successor()
}

// And here we will iterate that string and detect when our current index is relative in one of three different possible ways to the character selected previously
println("\n\nsomeIndexInTheMiddle = \(exampleString[someIndexInTheMiddle])")
for var index: String.Index = exampleString.startIndex; index != exampleString.endIndex; index = index.successor() {
    println(" - \(exampleString[index])")
    if index != exampleString.startIndex && index.predecessor() == someIndexInTheMiddle {
        println("current character comes after someIndexInTheMiddle")
    } else if index == someIndexInTheMiddle {
        println("current character is the one indicated by someIndexInTheMiddle")
    } else if index != exampleString.endIndex && index.successor() == someIndexInTheMiddle {
        println("Current character comes before someIndexinTheMiddle")
    }
}

希望这能提供必要的信息。

答案 3 :(得分:0)

无论你决定迭代String的是什么方式,你都会立即想要在一个函数中捕获迭代,该函数可以在使用应用于每个字符串字符的闭包时重复调用。如:

extension String {
  func each (f: (Character) -> Void) {
    for var index = self.startIndex;
        index < self.endIndex;
        index = index.successor() {
      f (string[index])
    }
  }
}

Apple已经为C-Strings提供了这些功能,并且一旦字符串访问固化就会用于一般字符串。