Swift 5: 字符串中字符的索引

8

在Swift 5之前,我有这个扩展程序可以工作:

  fileprivate extension String {
        func indexOf(char: Character) -> Int? {
            return firstIndex(of: char)?.encodedOffset
        }
    }

现在,我收到了一个弃用的消息:
'encodedOffset' is deprecated: encodedOffset has been deprecated as most common usage is incorrect. Use `utf16Offset(in:)` to achieve the same behavior.

除了使用utf16Offset(in:)之外,是否有更简单的解决方案?

我只需要将字符位置的索引作为Int返回。


3
不要使用 encodedOffset。使用集合距离 https://dev59.com/J1sW5IYBdhLWcg3w0aHM#34540310 - Leo Dabus
1个回答

11

经过一段时间,我不得不承认我的原始答案是不正确的。

在Swift中有两种方法:firstIndex(of:)lastIndex(of:)

两者都返回Int?,表示数组中第一个/最后一个与传递元素相等的元素的索引(如果有的话,否则返回nil)。

因此,应避免使用自定义方法来获取索引,因为可能有两个相同的元素,你将不知道需要哪个索引。因此,请考虑您的使用情况并决定哪个索引更适合您;首先还是最后一个。


原始回答:

utf16Offset(in:) 有什么问题吗?这是Swift 5的正确用法。

fileprivate extension String {
    func indexOf(char: Character) -> Int? {
        return firstIndex(of: char)?.utf16Offset(in: self)
    }
}

2
我已经陈述完毕!我在使用 utf16Offset(in: self) 部分遇到了问题。 - Gizmodo
7
你应该使用集合距离方法 distance(from start: String.Index, to end: String.Index) -> String.IndexDistance。这个方法可以计算两个字符串索引之间的距离,返回的是一个索引的整数差值。 - Leo Dabus
4
尝试运行 "".indexOf(char: "") // 4 的代码。 - Leo Dabus
5
可以确认这不是正确的答案;Leo Dabus的评论应该成为一个答案并标记为被接受。由于“Character”表示大小不同的字形簇,UTF-16偏移量存在问题。无论字符大小的组合如何,将每个字符串都视为UTF-16是明显错误的。唯一正确的方法是使用集合函数在“Int”偏移量和“String.Index”之间进行转换。 - Joshua Nozzi
1
我只是想指出@LeoDabus是正确的,并以最简单的方式指出了缺陷。我一直看到UTF-16偏移量的答案,但我知道由于这个原因它是不正确的。我计划为解析器实现indexDistance。 - Lloyd Sargent
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接