Answers:
如果您使用的是Swift 3,则可以忽略此答案的第二部分。好消息是,这实际上现在又很简洁!仅使用String的新remove(at :)方法。
var myString = "Hello, World"
myString.remove(at: myString.startIndex)
myString // "ello, World"
我喜欢此dropFirst()
功能。
let original = "Hello" // Hello
let sliced = dropFirst(original) // ello
它简短,清晰,适用于符合Sliceable协议的任何内容。
如果您使用的是Swift 2,则此答案已更改。您仍然可以使用dropFirst,但不能不从字符串characters
属性中删除第一个字符,然后将结果转换回字符串。dropFirst也已成为方法,而不是函数。
let original = "Hello" // Hello
let sliced = String(original.characters.dropFirst()) // ello
另一种选择是使用后缀函数来拼接字符串的UTF16View
。当然,此后也必须将其转换回String。
let original = "Hello" // Hello
let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // ello
这就是说我最初提供的解决方案并不是在较新版本的Swift中最简洁的方法。removeAtIndex()
如果您正在寻找一个简短而直观的解决方案,我建议您使用@chris'解决方案。
var original = "Hello" // Hello
let removedChar = original.removeAtIndex(original.startIndex)
original // ello
正如@vacawama在下面的注释中所指出的,不修改原始String的另一个选项是使用substringFromIndex。
let original = "Hello" // Hello
let substring = original.substringFromIndex(advance(original.startIndex, 1)) // ello
或者,如果您恰巧希望将某个字符从String的开头和结尾删除,则可以使用substringWithRange。只要确保在发生这种情况时要警惕startIndex + n > endIndex - m
。
let original = "Hello" // Hello
let newStartIndex = advance(original.startIndex, 1)
let newEndIndex = advance(original.endIndex, -1)
let substring = original.substringWithRange(newStartIndex..<newEndIndex) // ell
最后一行也可以使用下标符号书写。
let substring = original[newStartIndex..<newEndIndex]
remove(at:)
方法的返回值:它是删除的字符,而不是新的字符串。例如,let removedCharacter = myString.remove(at: myString.startIndex)
。我在返回方法调用的结果时犯了一个错误,忘记了这种方法就是这种情况。祝大家编码愉快!
Swift 4更新
在Swift 4中,再次String
符合Collection
,因此可以使用dropFirst
和dropLast
修剪字符串的开头和结尾。结果为类型Substring
,因此您需要将其传递给String
构造函数以获取a String
:
let str = "hello"
let result1 = String(str.dropFirst()) // "ello"
let result2 = String(str.dropLast()) // "hell"
dropFirst()
并指定dropLast()
一个Int
要删除的字符数:
let result3 = String(str.dropLast(3)) // "he"
let result4 = String(str.dropFirst(4)) // "o"
如果您指定的要删除的字符多于字符串中的字符,则结果将是空字符串(""
)。
let result5 = String(str.dropFirst(10)) // ""
Swift 3更新
如果您只想删除第一个字符并想更改原始字符串,请参阅@MickMacCallum的答案。如果要在此过程中创建新字符串,请使用substring(from:)
。使用的扩展名String
,您可以隐藏的丑陋之处,substring(from:)
并substring(to:)
创建有用的添加物以修剪a的开头和结尾String
:
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return substring(from: index(startIndex, offsetBy: count))
}
func chopSuffix(_ count: Int = 1) -> String {
return substring(to: index(endIndex, offsetBy: -count))
}
}
"hello".chopPrefix() // "ello"
"hello".chopPrefix(3) // "lo"
"hello".chopSuffix() // "hell"
"hello".chopSuffix(3) // "he"
就像dropFirst
和dropLast
他们之前,这些功能会崩溃如果没有在字符串提供足够的字母。呼叫者有责任正确使用它们。这是一个有效的设计决策。可以编写它们以返回一个可选内容,然后调用者必须将其拆开。
斯威夫特2.x
在唉斯威夫特2,dropFirst
和dropLast
(之前的最佳解决方案)并不像他们以前那样方便。随着扩展String
,你可以隐藏的丑陋substringFromIndex
和substringToIndex
:
extension String {
func chopPrefix(count: Int = 1) -> String {
return self.substringFromIndex(advance(self.startIndex, count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringToIndex(advance(self.endIndex, -count))
}
}
"hello".chopPrefix() // "ello"
"hello".chopPrefix(3) // "lo"
"hello".chopSuffix() // "hell"
"hello".chopSuffix(3) // "he"
就像dropFirst
和dropLast
他们之前,这些功能会崩溃如果没有在字符串提供足够的字母。呼叫者有责任正确使用它们。这是一个有效的设计决策。可以编写它们以返回一个可选内容,然后调用者必须将其拆开。
在Swift 1.2中,您需要这样调用chopPrefix
:
"hello".chopPrefix(count: 3) // "lo"
或者,您可以_
在函数定义中添加下划线以隐藏参数名称:
extension String {
func chopPrefix(_ count: Int = 1) -> String {
return self.substringFromIndex(advance(self.startIndex, count))
}
func chopSuffix(_ count: Int = 1) -> String {
return self.substringToIndex(advance(self.endIndex, -count))
}
}
斯威夫特2.2
“ advance”不可用:在索引上调用“ advancedBy(n)”方法
func chopPrefix(count: Int = 1) -> String {
return self.substringFromIndex(self.startIndex.advancedBy(count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringFromIndex(self.endIndex.advancedBy(count))
}
斯威夫特3.0
func chopPrefix(_ count: Int = 1) -> String {
return self.substring(from: self.characters.index(self.startIndex, offsetBy: count))
}
func chopSuffix(_ count: Int = 1) -> String {
return self.substring(to: self.characters.index(self.endIndex, offsetBy: -count))
}
斯威夫特3.2
字符串内容作为字符集合的视图。
@available(swift, deprecated: 3.2, message: "Please use String or Substring directly") public var characters: String.CharacterView
func chopPrefix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
return self.substring(from: String.Index(encodedOffset: count))
}
return ""
}
func chopSuffix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
return self.substring(to: String.Index(encodedOffset: self.count - count))
}
return ""
}
斯威夫特4
extension String {
func chopPrefix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
let indexStartOfText = self.index(self.startIndex, offsetBy: count)
return String(self[indexStartOfText...])
}
return ""
}
func chopSuffix(_ count: Int = 1) -> String {
if count >= 0 && count <= self.count {
let indexEndOfText = self.index(self.endIndex, offsetBy: -count)
return String(self[..<indexEndOfText])
}
return ""
}
}
在Swift 2中,执行以下操作:
let cleanedString = String(theString.characters.dropFirst())
我建议https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html了解Swift字符串。
取决于最终结果是什么(变异与非变异)。
从Swift 4.1开始:
变异:
var str = "hello"
str.removeFirst() // changes str
非变异:
let str = "hello"
let strSlice = str.dropFirst() // makes a slice without the first letter
let str2 = String(strSlice)
笔记:
nonmutating
为了清楚起见,我在示例中增加了一个步骤。从主观上讲,将最后两个步骤结合起来会更加简洁。dropFirst
对我来说,命名似乎有点奇怪,因为如果我正确地理解了《Swift API设计指南》,那dropFirst
应该真的像是dropingFirst
因为它是不变的。只是一个想法 :)。droppingFirst
-他们搞砸了!
前面的答案非常好,但是到目前为止,我认为这可能是在Swift 4中从字符串中删除第一个字符的最简洁的方法:
var line: String = "This is a string..."
var char: Character? = nil
char = line.removeFirst()
print("char = \(char)") // char = T
print("line = \(line)") // line = his is a string ...
在Swift 2中使用以下String扩展名:
extension String
{
func substringFromIndex(index: Int) -> String
{
if (index < 0 || index > self.characters.count)
{
print("index \(index) out of bounds")
return ""
}
return self.substringFromIndex(self.startIndex.advancedBy(index))
}
}
display.text = display.text!.substringFromIndex(1)
“ en_US,fr_CA,es_US” .chopSuffix(5).chopPrefix(5)//“,fr_CA,”
extension String {
func chopPrefix(count: Int = 1) -> String {
return self.substringFromIndex(self.startIndex.advancedBy(count))
}
func chopSuffix(count: Int = 1) -> String {
return self.substringToIndex(self.endIndex.advancedBy(-count))
}
}
从字符串中删除第一个字符
let choppedString = String(txtField.text!.characters.dropFirst())
extension String {
func chopPrefix(_ count: UInt = 1) -> String {
return substring(from: characters.index(startIndex, offsetBy: Int(count)))
}
func chopSuffix(_ count: UInt = 1) -> String {
return substring(to: characters.index(endIndex, offsetBy: -Int(count)))
}
}
class StringChopTests: XCTestCase {
func testPrefix() {
XCTAssertEqual("original".chopPrefix(0), "original")
XCTAssertEqual("Xfile".chopPrefix(), "file")
XCTAssertEqual("filename.jpg".chopPrefix(4), "name.jpg")
}
func testSuffix() {
XCTAssertEqual("original".chopSuffix(0), "original")
XCTAssertEqual("fileX".chopSuffix(), "file")
XCTAssertEqual("filename.jpg".chopSuffix(4), "filename")
}
}
advance
通过强制转换display.text!
为NSString 来避免整个事情。我并不是说这是一个好的解决方案-只是纠正可能的误解。使用NSString,您可以使用Int对其进行索引。-您无法使用Int进行索引的原因不是因为Unicode;这是因为一个角色可以包含多个复合代码点。