我怎样才能得到字符串的第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,请参阅文档注释讨论
当前回答
对我来说最有效的方法是:
var firstName = "Olivia"
var lastName = "Pope"
var nameInitials.text = "\(firstName.prefix(1))" + "\ (lastName.prefix(1))"
输出:“OP”
其他回答
注意:请参阅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.
为了提供主题并显示快速下标的可能性,这里有一个基于“substring-toolbox”下标的小字符串
这些方法是安全的,并且不会遍历字符串索引
extension String {
// string[i] -> one string char
subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }
// string[pos,len] -> substring from pos for len chars on the left
subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }
// string[pos, len, .right2left] -> substring from pos for len chars on the right
subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }
// string[range] -> substring form start pos on the left to end pos on the right
subscript(range: Range<Int>) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }
// string[range, .right2left] -> substring start pos on the right to end pos on the left
subscript(range: Range<Int>, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }
var length: Int { return countElements(self) }
enum Mode { case pos_len, start_end }
enum Way { case left2right, right2left }
subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
if mode == .start_end {
if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
val2 = val2-val1
}
if way == .left2right {
val1 = min(self.length-1, max(0,val1))
val2 = min(self.length-val1, max(1,val2))
} else {
let val1_ = val1
val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
val2 = max(1, (self.length-1-val1_)-(val1-1) )
}
return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))
//-- Alternative code without bridge --
//var range: Range<Int> = pos...(pos+len-1)
//var start = advance(startIndex, range.startIndex)
//var end = advance(startIndex, range.endIndex)
//return self.substringWithRange(Range(start: start, end: end))
}
}
println("0123456789"[3]) // return "3"
println("0123456789"[3,2]) // return "34"
println("0123456789"[3,2,.right2left]) // return "56"
println("0123456789"[5,10,.pos_len,.left2right]) // return "56789"
println("0123456789"[8,120,.pos_len,.right2left]) // return "01"
println("0123456789"[120,120,.pos_len,.left2right]) // return "9"
println("0123456789"[0...4]) // return "01234"
println("0123456789"[0..4]) // return "0123"
println("0123456789"[0...4,.right2left]) // return "56789"
println("0123456789"[4...0,.right2left]) // return "678" << because ??? range can wear endIndex at 0 ???
斯威夫特4
String(Array(stringToIndex)[index])
这可能是一次性解决这个问题的最好方法。您可能希望首先将String转换为数组,然后再将结果转换为String。否则,将返回字符而不是字符串。
示例String(Array("HelloThere")[1])将返回"e"作为字符串。
(数组("HelloThere")[1]将返回"e"作为字符。
Swift不允许字符串像数组一样被索引,但这就完成了工作,用蛮力的方式。
我的解决方案是在一行中,假设cadena是字符串,4是你想要的第n个位置:
let character = cadena[advance(cadena.startIndex, 4)]
简单的…我想Swift在未来的版本中会包含更多关于子字符串的内容。
在项目中包含此扩展
extension String{
func trim() -> String
{
return self.trimmingCharacters(in: NSCharacterSet.whitespaces)
}
var length: Int {
return self.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])
}
func substring(fromIndex: Int, toIndex:Int)->String{
let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
let endIndex = self.index(startIndex, offsetBy: toIndex-fromIndex)
return String(self[startIndex...endIndex])
}
然后像这样使用函数
let str = "Sample-String"
let substring = str.substring(fromIndex: 0, toIndex: 0) //returns S
let sampleSubstr = str.substring(fromIndex: 0, toIndex: 5) //returns Sample