我怎样才能得到字符串的第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,请参阅文档注释讨论
当前回答
斯威夫特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 ","
其他回答
我也有同样的问题。简单地这样做:
var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(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指出我在使用索引属性作为字符串下标的(其他)替代方案的方向!
对我来说最有效的方法是:
var firstName = "Olivia"
var lastName = "Pope"
var nameInitials.text = "\(firstName.prefix(1))" + "\ (lastName.prefix(1))"
输出:“OP”
一个类似蟒蛇的解决方案,允许你使用负下标,
var str = "Hello world!"
str[-1] // "!"
可能是:
extension String {
subscript (var index:Int)->Character{
get {
let n = distance(self.startIndex, self.endIndex)
index %= n
if index < 0 { index += n }
return self[advance(startIndex, index)]
}
}
}
顺便说一下,调换整个python的切片符号可能是值得的
我想指出的是,如果你有一个很大的字符串,并且需要从中随机访问许多字符,你可能想要支付额外的内存成本,并将字符串转换为一个数组以获得更好的性能:
// 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])
}