[英]Convert String.Index to Int or Range<String.Index> to NSRange
所以我发现了与将NSRange
转换为Range<String.Index>
的情况有关的问题,但我实际上遇到了相反的问题。
很简单,我有一个String
和一个Range<String.Index>
并且需要将后者转换为NSRange
以与旧函数一起使用。
到目前为止,我唯一的解决方法是像这样抓取一个子字符串:
func foo(theString: String, inRange: Range<String.Index>?) -> Bool {
let theSubString = (nil == inRange) ? theString : theString.substringWithRange(inRange!)
return olderFunction(theSubString, NSMakeRange(0, countElements(theSubString)))
}
这当然有效,但它不是很漂亮,我宁愿避免必须获取子字符串并以某种方式使用范围本身,这可能吗?
如果您查看String.Index
的定义,您会发现:
struct Index : BidirectionalIndexType, Comparable, Reflectable {
/// Returns the next consecutive value after `self`.
///
/// Requires: the next value is representable.
func successor() -> String.Index
/// Returns the previous consecutive value before `self`.
///
/// Requires: the previous value is representable.
func predecessor() -> String.Index
/// Returns a mirror that reflects `self`.
func getMirror() -> MirrorType
}
所以实际上没有办法将它转换为Int
并且这是有充分理由的。 根据字符串的编码,单个字符占用不同数量的字节。 唯一的方法是计算需要多少successor
操作才能达到所需的String.Index
。
编辑String
的定义在各种 Swift 版本中发生了变化,但基本上是相同的答案。 要查看最新的定义,只需 CMD 键单击 XCode 中的String
定义即可到达根目录(也适用于其他类型)。
distanceTo
是适用于各种协议的扩展。 只需在 CMD 单击后在String
源中查找它。
我不知道是哪个版本引入了它,但在 Swift 4.2 中,您可以轻松地在两者之间进行转换。
将Range<String.Index>
转换为NSRange
:
let range = s[s.startIndex..<s.endIndex]
let nsRange = NSRange(range, in: s)
要将NSRange
转换为Range<String.Index>
:
let nsRange = NSMakeRange(0, 4)
let range = Range(nsRange, in: s)
请记住, NSRange
是基于 UTF-16 的,而Range<String.Index>
是基于Character
的。 因此,您不能仅使用计数和位置在两者之间进行转换!
let index: Int = string.startIndex.distanceTo(range.startIndex)
在 Swift 4 中, distanceTo()
已弃用。 您可能必须将String
转换为NSString
以利用其-[NSString rangeOfString:]
方法,该方法返回一个NSRange
。
Swift 4 完整解决方案:
OffsetIndexableCollection(使用 Int 索引的字符串)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-
let a = "01234"
print(a[0]) // 0
print(a[0...4]) // 01234
print(a[...]) // 01234
print(a[..<2]) // 01
print(a[...2]) // 012
print(a[2...]) // 234
print(a[2...3]) // 23
print(a[2...2]) // 2
if let number = a.index(of: "1") {
print(number) // 1
print(a[number...]) // 1234
}
if let number = a.index(where: { $0 > "1" }) {
print(number) // 2
}
您可以使用此函数并在需要转换时调用它
extension String
{
func CnvIdxTooIntFnc(IdxPsgVal: Index) -> Int
{
return startIndex.distanceTo(IdxPsgVal)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.