Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较String.Index值_String_Macos_Swift - Fatal编程技术网

比较String.Index值

比较String.Index值,string,macos,swift,String,Macos,Swift,是否可以比较Swift中的两个String.Index值?我试图一个字符一个字符地处理一个字符串,有几次我需要检查我是否在字符串的末尾。我已经试过了 while (currentIndex < string.endIndex) { //do things... currentIndex = currentIndex.successor() } while(currentIndex

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

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

它抱怨类型转换。然后,我尝试定义并重载
字符串索引支持
=
=。字符串索引是不透明类型,不是整数,不能与整数进行比较

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


最简单的选项是
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()
}
var string=“你好,世界”
var currentIndex=string.startIndex
@中缀函数布尔{
返回距离(左、右)大于0
}
while(currentIndex
我相信这个REPL/PLAYOND示例应该说明您(和其他人)需要了解的有关使用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")
    }
}

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

无论您决定以何种方式对
字符串进行迭代,您都会立即希望在一个函数中捕获迭代,该函数可以在对每个字符串应用闭包时重复调用。例如:

extension String {
  func each (f: (Character) -> Void) {
    for var index = self.startIndex;
        index < self.endIndex;
        index = index.successor() {
      f (string[index])
    }
  }
}
扩展字符串{
func每个(f:(字符)->Void){
对于var指数=self.startIndex;
指数

苹果已经为C字串提供了这些功能,一旦字符访问固化,苹果将为普通字串提供这些功能。

覆盖运算符不是解决方案。显然,在Swift 3中覆盖
,似乎
我意识到这是正确的答案,但作为一个附带问题,有什么方法可以检查一个索引是在另一个索引之前还是之后?如果这样做,您将错过最后一个索引。如果调用
currentIndex.succession
,则只能错过最后一个字符。但请提交一份bug报告,这是测试版。还要注意的是,在第4节中有一个很大的变化,所以很有可能会有改进。整个unicode问题仍然有很多问题,但是苹果和Swift解决了很多问题。是的,字符串肯定有一些限制。唯一一个需要执行复杂字符串操作的项目是我坚持使用CFString。我怀疑我正在利用的一些更高级的东西永远不可能使用字符串。使用
CFString
的问题是,它不会处理表情符号,代理项对不是组合的,比如标志字符,它们都不能在UTF-16
unichar
中表示。这就是我要寻找的
O(n)
性能有点烦人,尽管可能不会对我正在使用的字符串造成任何问题。为什么你会说使用操作符重载是个坏主意?@Jumhyn注意字符串类当前充满了
O(n)
性能问题。不管怎样,你都会遇到他们。这似乎是课堂上的一个普遍设计缺陷。毫无疑问,他们总有一天会修复它,但现在我们只需要接受它——或者使用NS/CFString。稍后,当其他人正在编写代码时,他们将不理解其用法。再加上大量的开发人员使各种事情超载,这将导致灾难。最好的解决方案是最清晰的解决方案,这一解决方案稍后将导致每分钟WTF数减少。@AbhiBeckert但是
CFString
NSString
在处理表情符号、代理项对和组合(如标记字符)时都存在重大问题,这些都无法在UTF-16 unichar中表示。尤其是表情符号的出现频率越来越高。String.utf16为您提供了另一种表示方式,它更接近NSString和CFString索引的工作方式。您可以使用整数索引并对索引进行计算,但目前,它缺少查找和匹配字符串的函数,因此您必须自己实现这些函数。它还受到NSString和CFString的所有缺点的影响。
// 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")
    }
}
extension String {
  func each (f: (Character) -> Void) {
    for var index = self.startIndex;
        index < self.endIndex;
        index = index.successor() {
      f (string[index])
    }
  }
}