What is the best way to remove the first character from a string in Swift?

I want to remove the first character from a string. So far, the shortest thing I've come up with is:

display.text = display.text!.substringFromIndex(advance(display.text!.startIndex, 1)) 

I know that we cannot index a string with Int due to Unicode, but this solution seems awfully detailed. Is there any other way that I skip?

+62
string swift
Feb 11 '15 at 3:07
source share
11 answers

If you use Swift 3 , you can ignore the second section of this answer. The good news is that now it is really concise! Just using String new remove (at :) method.

 var myString = "Hello, World" myString.remove(at: myString.startIndex) myString // "ello, World" 



I like the global dropFirst() function for this.

 let original = "Hello" // Hello let sliced = dropFirst(original) // ello 

It is short, straightforward, and works for anything that complies with the Sliceable protocol.

If you are using Swift 2 , this answer has changed. You can still use dropFirst, but not excluding the first character from your characters property and then return the result in String. dropFirst has also become a method, not a function.

 let original = "Hello" // Hello let sliced = String(original.characters.dropFirst()) // ello 

Another alternative is to use the suffix function to UTF16View string. Of course, this also needs to be converted back to string.

 let original = "Hello" // Hello let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // ello 

All of this means that the solution I originally provided was not the shortest way to do this in new versions of Swift. I recommend abandoning the @chris solution with removeAtIndex() if you are looking for a short and intuitive solution.

 var original = "Hello" // Hello let removedChar = original.removeAtIndex(original.startIndex) original // ello 

And as @vacawama pointed out in the comments below, another option that doesn't change the original string is to use substringFromIndex.

 let original = "Hello" // Hello let substring = original.substringFromIndex(advance(original.startIndex, 1)) // ello 

Or, if you are lucky enough to discard a character from the beginning and end of a string, you can use substringWithRange. Just remember to protect against conditions when 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 

The last line can also be written using index notation.

 let substring = original[newStartIndex..<newEndIndex] 
+137
Feb 11 '15 at 3:31 on
source share

Update for Swift 4

In Swift 4, String again matches Collection , so you can use dropFirst and dropLast to trim the beginning and end of the lines. The result is of type Substring , so you need to pass this to the String constructor to return a String :

 let str = "hello" let result1 = String(str.dropFirst()) // "ello" let result2 = String(str.dropLast()) // "hell" 

dropFirst() and dropLast() also take Int to indicate the number of characters to remove:

 let result3 = String(str.dropLast(3)) // "he" let result4 = String(str.dropFirst(4)) // "o" 

If you specify more characters than the string, the result is an empty string ( "" ).

 let result5 = String(str.dropFirst(10)) // "" 



Update for Swift 3

If you just want to remove the first character and want to change the original string in place, refer to @MickMacCallum's answer. If you want to create a new chain in this process, use substring(from:) . With the extension to String you can hide the ugliness of substring(from:) and substring(to:) to create useful additions to trim the beginning and end of 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" 

Like the dropFirst and dropLast in front of them, these functions will break if there are not enough letters in the String. The burden depends on whether you use it. This is a valid design decision. You could write them to return an option, which then needs to be deployed by the caller.




Swift 2.x

Alas, in Swift 2 , dropFirst and dropLast (the previous best solution) are not as convenient as before. With the extension to String you can hide the ugliness of substringFromIndex and 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" 

Like the dropFirst and dropLast in front of them, these functions will break if there are not enough letters in the String. The burden depends on whether you use it. This is a valid design decision. You could write them to return an option, which then needs to be deployed by the caller.




In Swift 1.2, you need to call chopPrefix as follows:

 "hello".chopPrefix(count: 3) // "lo" 

or you can add the underscore _ in function definitions to suppress the parameter name:

 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)) } } 
+43
Jun 14 '15 at 13:34 on
source share

In Swift 2, do the following:

 let cleanedString = String(theString.characters.dropFirst()) 

I recommend https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html to understand Swift lines.

+12
Aug 29 '15 at 12:30
source share

Swift 2.2

'advance' is not available: call advancedBy (n) on the index

  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)) } 

Swift 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)) } 

Swift 4

Type of string content as a character set.

 @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 "" } 
+11
Jun 14 '16 at 10:20
source share

How about this?

 s.removeAtIndex(s.startIndex) 

This, of course, assumes your string is mutable. It returns a character that has been deleted, but modifies the original string.

+6
Feb 11 '15 at 3:15
source share

I don't know anything more compressed out of the box, but you can easily implement the ++ prefix, for example,

 public prefix func ++ <I: ForwardIndexType>(index: I) -> I { return advance(index, 1) } 

After that, you can use it in your heart very briefly:

 str.substringFromIndex(++str.startIndex) 
+1
Feb 11 '15 at 3:12
source share

In Swift 2, use this line extension:

 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) 
+1
Sep 22 '15 at 2:37
source share

"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)) } } 
+1
Jun 30 '16 at 4:15
source share

To remove the first character from a string

 let choppedString = String(txtField.text!.characters.dropFirst()) 
0
Oct 05 '16 at 4:43
source share

Swift3

 extension String { func chopPrefix(_ count: Int = 1) -> String { return substring(from: characters.index(startIndex, offsetBy: count)) } func chopSuffix(_ count: Int = 1) -> String { return substring(to: characters.index(endIndex, offsetBy: -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") } } 
0
Nov 29 '16 at 15:09
source share

Below is the Swift4 version for disaster recovery of the chopPrefix extension, leaving chopSuffix in the community ...

 extension String { func chopPrefix(_ count: Int = 1) -> String { return count>self.count ? self : String(self[index(self.startIndex, offsetBy: count)...]) } } 
0
Oct 02 '17 at 0:25
source share



All Articles