简体   繁体   English

比较String.Index值

[英]Comparing String.Index values

Is it possible to compare two String.Index values in Swift? 在Swift中可以比较两个String.Index值吗? I'm trying to process a string character by character, and several times I need to check if I am at the end of the string. 我正在尝试逐个字符地处理字符串,并且需要多次检查我是否在字符串的末尾。 I've tried just doing 我已经尝试过

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

Which complained about type conversions. 其中抱怨类型转换。 Then, I tried defining and overload for < as such: 然后,我尝试为<定义和重载,如下所示:

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

Which gets rid of compilation errors, but I have no clue what to do in order to compare lhs and rhs properly. 这摆脱了编译错误,但是我不知道如何正确比较lhsrhs Is this the way I should go about using String.Index , or is there a better way to compare them? 这是我应该使用String.Index ,还是有更好的比较方式?

String indexes support = and != . 字符串索引支持=!= String indexes are an opaque type, not integers and can not be compared like integers. 字符串索引是不透明的类型,不是整数,不能像整数一样进行比较。

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

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

The simplest option is the distance() function: 最简单的选项是distance()函数:

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

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

Beware distance() has O(N) performance, so avoid it for large strings. 当心distance()具有O(N)性能,因此对于大型字符串,请避免使用它。 However, the entire String class doesn't currently handle large strings anyway — you should probably switch to CFString if performance is critical. 但是,整个String类当前都无法处理大字符串-如果性能至关重要,则应该切换到CFString

Using an operator overload is a bad idea, but just as a learning exercise this is how you'd do it: 使用运算符重载是一个坏主意,但是就像学习练习一样,这是您要执行的操作:

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()
}

I believe this REPL/Playground example should illuminate what you (and others) need to know about working with the String.Index concept. 我相信这个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")
    }
}

Hopefully that provides the necessary information. 希望能提供必要的信息。

Whatever way you decide to iterator over a String , you will immediately want to capture the iteration in a function that can be repeatedly invoked while using a closure applied to each string character. 无论您决定对String进行迭代的哪种方式,您都将立即想要捕获函数中的迭代,该函数可以在使用应用于每个字符串字符的闭包时重复调用。 As in: 如:

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

Apple already provides these for C-Strings and will for general strings as soon as they get character access solidified. Apple已经为C字符串提供了这些功能,并且一旦它们巩固了字符访问功能,便会为通用字符串提供这些功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM