I want to delete the first character from a string. So far, the most succinct thing I've come up with is:
display.text = display.text!.substringFromIndex(advance(display.text!.startIndex, 1))
I know we can't index into a string with an Int
because of Unicode, but this solution seems awfully verbose. Is there another way that I'm overlooking?
Swift String dropFirst() The dropFirst() method removes the first character of the string.
To remove the specific character from a string, we can use the built-in remove() method in Swift. The remove() method takes the character position as an argument and removed it from the string.
To remove the first character from a string , we can use the built-in removeFirst() method in Swift.
If you're using Swift 3, you can ignore the second section of this answer. Good news is, this is now actually succinct again! Just using String's 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's short, clear, and works for anything that conforms to the Sliceable protocol.
If you're using Swift 2, this answer has changed. You can still use dropFirst, but not without dropping the first character from your strings characters
property and then converting the result back to a 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 splice the string's UTF16View
. Of course, this has to be converted back to a String afterwards as well.
let original = "Hello" // Hello let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // ello
All this is to say that the solution I originally provided has turned out not to be the most succinct way of doing this in newer versions of Swift. I recommend falling back on @chris' solution using removeAtIndex()
if you're looking for a short and intuitive solution.
var original = "Hello" // Hello let removedChar = original.removeAtIndex(original.startIndex) original // ello
And as pointed out by @vacawama in the comments below, another option that doesn't modify the original String is to use substringFromIndex.
let original = "Hello" // Hello let substring = original.substringFromIndex(advance(original.startIndex, 1)) // ello
Or if you happen to be looking to drop a character off the beginning and end of the String, you can use substringWithRange. Just be sure to guard against the condition 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 subscript notation.
let substring = original[newStartIndex..<newEndIndex]
Update for Swift 4
In Swift 4, String
conforms to Collection
again, so it is possible to use dropFirst
and dropLast
to trim the beginnings and ends of strings. The result is of type Substring
, so you need to pass that to the String
constructor to get back a String
:
let str = "hello" let result1 = String(str.dropFirst()) // "ello" let result2 = String(str.dropLast()) // "hell"
dropFirst()
and dropLast()
also take an Int
to specify the number of characters to drop:
let result3 = String(str.dropLast(3)) // "he" let result4 = String(str.dropFirst(4)) // "o"
If you specify more characters to drop than are in the string, the result will be the 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, then see @MickMacCallum's answer. If you want to create a new string in the process, use substring(from:)
. With an extension to String
, you can hide the ugliness of substring(from:)
and substring(to:)
to create useful additions to trim the start and ends of 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"
Like dropFirst
and dropLast
before them, these functions will crash if there aren't enough letters available in the String. The onus is on the caller to use them properly. This is a valid design decision. One could write them to return an optional which then would have to be unwrapped by the caller.
Swift 2.x
Alas in Swift 2, dropFirst
and dropLast
(the previous best solution) aren't as convenient as they were before. With an 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 dropFirst
and dropLast
before them, these functions will crash if there aren't enough letters available in the String. The onus is on the caller to use them properly. This is a valid design decision. One could write them to return an optional which then would have to be unwrapped by the caller.
In Swift 1.2, you'll need to call chopPrefix
like this:
"hello".chopPrefix(count: 3) // "lo"
or you can add an underscore _
to the 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)) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With