我怎样才能得到字符串的第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,请参阅文档注释讨论
当前回答
我的解决方案是在一行中,假设cadena是字符串,4是你想要的第n个位置:
let character = cadena[advance(cadena.startIndex, 4)]
简单的…我想Swift在未来的版本中会包含更多关于子字符串的内容。
其他回答
我刚想出了一个巧妙的变通办法
var firstChar = Array(string)[0]
Swift 4.2或更高版本
使用String的indexes属性进行范围和部分范围下标
作为@LeoDabus nice answer的变体,我们可以为DefaultIndices添加一个额外的扩展,目的是允许我们在为后者实现自定义下标(通过Int专用范围和部分范围)时使用String的indexes属性。
extension DefaultIndices {
subscript(at: Int) -> Elements.Index { index(startIndex, offsetBy: at) }
}
// Moving the index(_:offsetBy:) to an extension yields slightly
// briefer implementations for these String extensions.
extension String {
subscript(range: Range<Int>) -> SubSequence {
let start = indices[range.lowerBound]
return self[start..<indices[start...][range.count]]
}
subscript(range: ClosedRange<Int>) -> SubSequence {
let start = indices[range.lowerBound]
return self[start...indices[start...][range.count]]
}
subscript(range: PartialRangeFrom<Int>) -> SubSequence {
self[indices[range.lowerBound]...]
}
subscript(range: PartialRangeThrough<Int>) -> SubSequence {
self[...indices[range.upperBound]]
}
subscript(range: PartialRangeUpTo<Int>) -> SubSequence {
self[..<indices[range.upperBound]]
}
}
let str = "foo bar baz bax"
print(str[4..<6]) // "ba"
print(str[4...6]) // "bar"
print(str[4...]) // "bar baz bax"
print(str[...6]) // "foo bar"
print(str[..<6]) // "foo ba"
感谢@LeoDabus指出我在使用索引属性作为字符串下标的(其他)替代方案的方向!
允许负指数
它总是有用的,不必总是写string[string]。长度- 1]用于在使用下标扩展名时获取最后一个字符。这(Swift 3)扩展允许负索引,范围和CountableClosedRange。
extension String {
var count: Int { return self.characters.count }
subscript (i: Int) -> Character {
// wraps out of bounds indices
let j = i % self.count
// wraps negative indices
let x = j < 0 ? j + self.count : j
// quick exit for first
guard x != 0 else {
return self.characters.first!
}
// quick exit for last
guard x != count - 1 else {
return self.characters.last!
}
return self[self.index(self.startIndex, offsetBy: x)]
}
subscript (r: Range<Int>) -> String {
let lb = r.lowerBound
let ub = r.upperBound
// quick exit for one character
guard lb != ub else { return String(self[lb]) }
return self[self.index(self.startIndex, offsetBy: lb)..<self.index(self.startIndex, offsetBy: ub)]
}
subscript (r: CountableClosedRange<Int>) -> String {
return self[r.lowerBound..<r.upperBound + 1]
}
}
如何使用:
var text = "Hello World"
text[-1] // d
text[2] // l
text[12] // e
text[0...4] // Hello
text[0..<4] // Hell
对于更彻底的程序员:在这个扩展中包括一个防止空字符串的保护
subscript (i: Int) -> Character {
guard self.count != 0 else { return '' }
...
}
subscript (r: Range<Int>) -> String {
guard self.count != 0 else { return "" }
...
}
斯威夫特4.2
这个答案是理想的,因为它在一个扩展中扩展了String及其所有子序列(Substring)
public extension StringProtocol {
public subscript (i: Int) -> Element {
return self[index(startIndex, offsetBy: i)]
}
public subscript (bounds: CountableClosedRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start...end]
}
public subscript (bounds: CountableRange<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start..<end]
}
public subscript (bounds: PartialRangeUpTo<Int>) -> SubSequence {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex..<end]
}
public subscript (bounds: PartialRangeThrough<Int>) -> SubSequence {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex...end]
}
public subscript (bounds: CountablePartialRangeFrom<Int>) -> SubSequence {
let start = index(startIndex, offsetBy: bounds.lowerBound)
return self[start..<endIndex]
}
}
使用
var str = "Hello, playground"
print(str[5...][...5][0])
// Prints ","
我想指出的是,如果你有一个很大的字符串,并且需要从中随机访问许多字符,你可能想要支付额外的内存成本,并将字符串转换为一个数组以获得更好的性能:
// 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])
}