我怎样才能得到字符串的第n个字符?我尝试了括号([])访问器,没有运气。
var string = "Hello, world!"
var firstChar = string[0] // Throws error
错误:'下标'是不可用的:不能下标String与Int,请参阅文档注释讨论
我怎样才能得到字符串的第n个字符?我尝试了括号([])访问器,没有运气。
var string = "Hello, world!"
var firstChar = string[0] // Throws error
错误:'下标'是不可用的:不能下标String与Int,请参阅文档注释讨论
当前回答
这是最好最简单的方法之一
let yourString = "thisString"
print(Array(yourString)[8])
将字符串中的每个字母放入数组 然后选择第9个
其他回答
注意:请参阅Leo Dabus关于正确实现Swift 4和Swift 5的回答。
Swift 4或更高版本
Substring类型是在Swift 4中引入的,用于生成子字符串 通过与原始字符串共享存储,更快更有效,这就是下标函数应该返回的。
在这里试试吧
extension StringProtocol {
subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
subscript(range: Range<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: ClosedRange<Int>) -> SubSequence {
let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
return self[startIndex..<index(startIndex, offsetBy: range.count)]
}
subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}
要将子字符串转换为字符串,您可以简单地 做字符串(字符串[0..2]),但你应该只做如果 您计划保留子字符串。否则,就更多了 有效地保持它为Substring。
It would be great if someone could figure out a good way to merge these two extensions into one. I tried extending StringProtocol without success, because the index method does not exist there. Note: This answer has been already edited, it is properly implemented and now works for substrings as well. Just make sure to use a valid range to avoid crashing when subscripting your StringProtocol type. For subscripting with a range that won't crash with out of range values you can use this implementation
为什么这不是内置的?
错误消息显示“请参阅文档注释以进行讨论”。Apple在文件unavailablestringapi .swift中提供了以下解释:
Subscripting strings with integers is not available. The concept of "the ith character in a string" has different interpretations in different libraries and system components. The correct interpretation should be selected according to the use case and the APIs involved, so String cannot be subscripted with an integer. Swift provides several different ways to access the character data stored inside strings. String.utf8 is a collection of UTF-8 code units in the string. Use this API when converting the string to UTF-8. Most POSIX APIs process strings in terms of UTF-8 code units. String.utf16 is a collection of UTF-16 code units in string. Most Cocoa and Cocoa touch APIs process strings in terms of UTF-16 code units. For example, instances of NSRange used with NSAttributedString and NSRegularExpression store substring offsets and lengths in terms of UTF-16 code units. String.unicodeScalars is a collection of Unicode scalars. Use this API when you are performing low-level manipulation of character data. String.characters is a collection of extended grapheme clusters, which are an approximation of user-perceived characters. Note that when processing strings that contain human-readable text, character-by-character processing should be avoided to the largest extent possible. Use high-level locale-sensitive Unicode algorithms instead, for example, String.localizedStandardCompare(), String.localizedLowercaseString, String.localizedStandardRangeOfString() etc.
斯威夫特5.3
我觉得这很优雅。“Hacking with Swift”的Paul Hudson提出了以下解决方案:
@available (macOS 10.15, * )
extension String {
subscript(idx: Int) -> String {
String(self[index(startIndex, offsetBy: idx)])
}
}
然后,要从字符串中获取一个字符,你只需做:
var string = "Hello, world!"
var firstChar = string[0] // No error, returns "H" as a String
注意:我只是想补充,这将返回一个字符串指出在评论。我认为这对Swift用户来说可能是意想不到的,但我经常需要一个字符串来直接在我的代码中使用,而不是字符类型,所以它确实简化了我的代码,避免了后来从字符到字符串的转换。
不使用整数进行索引,只使用String.Index。主要是线性复杂度。您还可以从String中创建范围。索引并使用它们获取子字符串。
斯威夫特3.0
let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]
let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]
快2.倍
let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]
let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]
请注意,不能使用从一个字符串到另一个字符串创建的索引(或范围)
let index10 = someString.startIndex.advanceBy(10)
//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]
斯威夫特3:
extension String {
func substring(fromPosition: UInt, toPosition: UInt) -> String? {
guard fromPosition <= toPosition else {
return nil
}
guard toPosition < UInt(characters.count) else {
return nil
}
let start = index(startIndex, offsetBy: String.IndexDistance(fromPosition))
let end = index(startIndex, offsetBy: String.IndexDistance(toPosition) + 1)
let range = start..<end
return substring(with: range)
}
}
"ffaabbcc".substring(fromPosition: 2, toPosition: 5) // return "aabb"
我想指出的是,如果你有一个很大的字符串,并且需要从中随机访问许多字符,你可能想要支付额外的内存成本,并将字符串转换为一个数组以获得更好的性能:
// Pay up front for O(N) memory
let chars = Array(veryLargeString.characters)
for i in 0...veryLargeNumber {
// Benefit from O(1) access
print(chars[i])
}