我怎样才能得到字符串的第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,请参阅文档注释讨论
当前回答
我想指出的是,如果你有一个很大的字符串,并且需要从中随机访问许多字符,你可能想要支付额外的内存成本,并将字符串转换为一个数组以获得更好的性能:
// 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])
}
其他回答
下标在这里很有用
但是字符串下标将把参数作为字符串。索引,所以很多人都搞不懂如何传递字符串。索引以获取如何形成字符串的详细信息。索引根据我们的要求,请参阅以下苹果文档
在这里,我创建了一个扩展方法来获取字符串中的第n个字符
extension String {
subscript(i: Int) -> String {
return i < count ? String(self[index(startIndex, offsetBy: i)]) : ""
}
}
使用
let name = "Narayana Rao"
print(name[11]) //o
print(name[1]) //a
print(name[0]) //N
print(name[30]) //""
如果你传递的索引超出了字符串计数的范围,它将返回空字符串
我刚想出了一个巧妙的变通办法
var firstChar = Array(string)[0]
斯威夫特3
extension String {
public func charAt(_ i: Int) -> Character {
return self[self.characters.index(self.startIndex, offsetBy: i)]
}
public subscript (i: Int) -> String {
return String(self.charAt(i) as Character)
}
public subscript (r: Range<Int>) -> String {
return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
}
public subscript (r: CountableClosedRange<Int>) -> String {
return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
}
}
使用
let str = "Hello World"
let sub = str[0...4]
有用的编程技巧和技巧(我写的)
我认为获取第一个字符的快速答案可能是:
let firstCharacter = aString[aString.startIndex]
它的优雅和性能比:
let firstCharacter = Array(aString.characters).first
但. .如果你想操纵和做更多的操作与字符串,你可以考虑创建一个扩展..这是一个扩展与这种方法,它非常类似于已经在这里张贴:
extension String {
var length : Int {
return self.characters.count
}
subscript(integerIndex: Int) -> Character {
let index = startIndex.advancedBy(integerIndex)
return self[index]
}
subscript(integerRange: Range<Int>) -> String {
let start = startIndex.advancedBy(integerRange.startIndex)
let end = startIndex.advancedBy(integerRange.endIndex)
let range = start..<end
return self[range]
}
}
但这是个糟糕的主意!!
下面的扩展是非常低效的。每次使用整数访问字符串时,都会运行一个O(n)函数来提高其起始索引。在另一个线性循环中运行一个线性循环意味着这个for循环意外地是O(n2)——随着字符串长度的增加,这个循环所花费的时间呈二次方增加。
而不是这样做,你可以使用字符的字符串集合。
斯威夫特5.2
let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"
你需要将这个String扩展添加到你的项目中(它已经完全测试过了):
extension String {
var length: Int {
return count
}
subscript (i: Int) -> String {
return self[i ..< i + 1]
}
func substring(fromIndex: Int) -> String {
return self[min(fromIndex, length) ..< length]
}
func substring(toIndex: Int) -> String {
return self[0 ..< max(0, toIndex)]
}
subscript (r: Range<Int>) -> String {
let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
upper: min(length, max(0, r.upperBound))))
let start = index(startIndex, offsetBy: range.lowerBound)
let end = index(start, offsetBy: range.upperBound - range.lowerBound)
return String(self[start ..< end])
}
}
尽管Swift总是有开箱即用的解决方案来解决这个问题(没有字符串扩展,我在下面提供),我仍然强烈建议使用扩展。为什么?因为它为我从早期版本的Swift中节省了数十个小时的痛苦迁移,在早期版本中,String的语法几乎每次发布都要更改,但我所需要做的只是更新扩展的实现,而不是重构整个项目。做出你的选择。
let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'
let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"
String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"