我怎样才能得到字符串的第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,请参阅文档注释讨论
当前回答
下标在这里很有用
但是字符串下标将把参数作为字符串。索引,所以很多人都搞不懂如何传递字符串。索引以获取如何形成字符串的详细信息。索引根据我们的要求,请参阅以下苹果文档
在这里,我创建了一个扩展方法来获取字符串中的第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]) //""
如果你传递的索引超出了字符串计数的范围,它将返回空字符串
其他回答
斯威夫特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"
我也有同样的问题。简单地这样做:
var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(0)
我刚想出了一个巧妙的变通办法
var firstChar = Array(string)[0]
获取和设置下标(字符串和子字符串)- Swift 4.2
Swift 4.2, Xcode 10
我的回答是基于@ alcarlson的回答。 唯一的区别是你可以返回一个Substring或String(在某些情况下,一个字符)。您还可以获取和设置下标。 最后,我的回答比@alecarlson的回答更麻烦,也更长,因此,我建议你把它放在源文件中。
扩展:
public extension String {
public subscript (i: Int) -> Character {
get {
return self[index(startIndex, offsetBy: i)]
}
set (c) {
let n = index(startIndex, offsetBy: i)
replaceSubrange(n...n, with: "\(c)")
}
}
public subscript (bounds: CountableRange<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start ..< end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ..< end, with: s)
}
}
public subscript (bounds: CountableClosedRange<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start ... end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
return self[start ... end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex ... end]
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ... end, with: s)
}
}
public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex ..< end]
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ..< end, with: s)
}
}
public subscript (i: Int) -> String {
get {
return "\(self[index(startIndex, offsetBy: i)])"
}
set (c) {
let n = index(startIndex, offsetBy: i)
self.replaceSubrange(n...n, with: "\(c)")
}
}
public subscript (bounds: CountableRange<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[start ..< end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ..< end, with: s)
}
}
public subscript (bounds: CountableClosedRange<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[start ... end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
return "\(self[start ... end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: PartialRangeThrough<Int>) -> String {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[startIndex ... end])"
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ... end, with: s)
}
}
public subscript (bounds: PartialRangeUpTo<Int>) -> String {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[startIndex ..< end])"
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ..< end, with: s)
}
}
public subscript (i: Int) -> Substring {
get {
return Substring("\(self[index(startIndex, offsetBy: i)])")
}
set (c) {
let n = index(startIndex, offsetBy: i)
replaceSubrange(n...n, with: "\(c)")
}
}
}
public extension Substring {
public subscript (i: Int) -> Character {
get {
return self[index(startIndex, offsetBy: i)]
}
set (c) {
let n = index(startIndex, offsetBy: i)
replaceSubrange(n...n, with: "\(c)")
}
}
public subscript (bounds: CountableRange<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start ..< end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ..< end, with: s)
}
}
public subscript (bounds: CountableClosedRange<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[start ... end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
return self[start ... end]
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex ... end]
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ..< end, with: s)
}
}
public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return self[startIndex ..< end]
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ..< end, with: s)
}
}
public subscript (i: Int) -> String {
get {
return "\(self[index(startIndex, offsetBy: i)])"
}
set (c) {
let n = index(startIndex, offsetBy: i)
replaceSubrange(n...n, with: "\(c)")
}
}
public subscript (bounds: CountableRange<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[start ..< end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ..< end, with: s)
}
}
public subscript (bounds: CountableClosedRange<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[start ... end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
get {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
return "\(self[start ... end])"
}
set (s) {
let start = index(startIndex, offsetBy: bounds.lowerBound)
let end = index(endIndex, offsetBy: -1)
replaceSubrange(start ... end, with: s)
}
}
public subscript (bounds: PartialRangeThrough<Int>) -> String {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[startIndex ... end])"
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ... end, with: s)
}
}
public subscript (bounds: PartialRangeUpTo<Int>) -> String {
get {
let end = index(startIndex, offsetBy: bounds.upperBound)
return "\(self[startIndex ..< end])"
}
set (s) {
let end = index(startIndex, offsetBy: bounds.upperBound)
replaceSubrange(startIndex ..< end, with: s)
}
}
public subscript (i: Int) -> Substring {
get {
return Substring("\(self[index(startIndex, offsetBy: i)])")
}
set (c) {
let n = index(startIndex, offsetBy: i)
replaceSubrange(n...n, with: "\(c)")
}
}
}
不使用整数进行索引,只使用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]