我一直在用Swift 3更新我的一些旧代码和答案,但是当我使用Swift字符串和索引时,理解这些东西是一件痛苦的事情。
具体来说,我正在尝试以下内容:
let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5) // error
第二行给出了以下错误
“advancedBy”不可用:要将索引前进n步,请在生成索引的CharacterView示例上调用“index(_:offsetBy:)”。
我看到String
有以下方法。
str.index(after: String.Index)
str.index(before: String.Index)
str.index(String.Index, offsetBy: String.IndexDistance)
str.index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
一开始这些真的让我很困惑,所以我开始和它们一起玩,直到我理解它们。我在下面添加了一个答案,以说明如何使用它们。
5条答案
按热度按时间eulz3vhy1#
以下所有示例都使用
startIndex
和endIndex
startIndex
是第一个字符的索引endIndex
是最后一个字符后的索引。示例
使用Swift 4的one-sided ranges,范围可以简化为以下形式之一。
为了清楚起见,我将在下面的示例中使用完整形式,但为了可读性,您可能希望在代码中使用单侧范围。
after
如:
index(after: String.Index)
after
是指直接在给定索引之后的字符的索引。示例
before
如:
index(before: String.Index)
before
是指直接在给定索引之前的字符的索引。示例
offsetBy
如:
index(String.Index, offsetBy: String.IndexDistance)
offsetBy
值可以是正的或负的,并且从给定的索引开始。虽然它的类型是String.IndexDistance
,但您可以给它一个Int
。示例
limitedBy
如:
index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
limitedBy
用于确保偏移量不会导致索引超出边界。这是一个边界指数。由于偏移量有可能超过限制,因此此方法返回Optional。如果索引越界,则返回nil
。示例
如果偏移量是
77
而不是7
,则if
语句将被跳过。为什么需要String. index?
对于字符串使用
Int
索引会容易得多。你必须为每个字符串创建一个新的String.Index
的原因是Swift中的字符在后台并不都是相同的长度。一个Swift字符可以由一个、两个甚至更多的Unicode码位组成。因此,每个唯一的字符串必须计算其字符的索引。可以将这种复杂性隐藏在Int索引扩展之后,但我不愿意这样做。被提醒实际发生的事情是很好的。
bkhjykvo2#
如果你想隐藏这些函数的复杂性,你可以使用这个扩展:
nzk0hqpo3#
我很感激这个问题和所有的信息。对于String.Index,我有一个问题和一个答案。
我想看看是否有一个O(1)的方法来访问String中的Substring(或Character),因为string.index(startIndex,offsetBy:如果你看一下索引函数的定义,它的速度是O(n)。当然,我们可以这样做:
然后访问characterArray中的任何位置,然而SPACE复杂度是
n
=字符串长度,O(n),所以这有点浪费空间。我在看Xcode中的Swift.String文档,有一个冻结的公共结构体,名为
Index
。我们可以初始化为:然后简单地访问或打印String对象中的任何索引,如下所示:
这是可行的,这是伟大的,但什么是运行时和空间的复杂性这样做呢?好点了吗?
wgeznvg74#
fcy6dtqo5#
在tableViewController中创建UITextView。我使用了函数:textViewDidChange,然后检查return-key-input。如果检测到返回键输入,则删除返回键输入,并解除键盘。