2015-02-11 31 views
64

我想從字符串中刪除第一個字符。到目前爲止,最簡潔的事我已經想出是:什麼是從Swift中的字符串中刪除第一個字符的最簡潔的方法?

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

我知道我們不能索引與Int因爲Unicode字符,但這種方法看起來太過冗長。有沒有另一種我可以忽略的方式?

+3

其實你可以通過鑄造'display.text避免整個'advance'事情!'到的NSString。我不是說這是一個好的解決方案 - 只是糾正一個可能的誤解。使用NSString,你可以用Int來索引它。 - 你無法用Int進行索引的原因不是因爲Unicode;這是因爲一個字符可以由多個複合碼點組成。 – matt 2015-02-11 03:40:19

+0

如果你這樣做是爲了大寫'String',那麼Swift 3已經將'capitalized'函數引入'String'。 – 2017-03-27 11:43:10

回答

137

如果您使用Swift 3,您可以忽略此答案的第二部分。好消息是,這現在又變得簡潔了!只需使用String的新remove(at :)方法即可。


我喜歡這個全球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。當然,這也必須轉換回字符串。

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

這一切是說,我最初提供的解決方案已經被證明不是在斯威夫特的新版本這樣做的最簡潔的方式。如果您正在尋找一個簡短直觀的解決方案,我建議使用removeAtIndex()迴歸@chris的解決方案。

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

original // ello 

以及由在下面的評論@vacawama指出,不修改原始字符串的另一個選擇是使用substringFromIndex。

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

或者,如果您碰巧想要從字符串的開始和結尾刪除字符,則可以使用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] 
+2

它並不需要你踏入基金會的世界。 – matt 2015-02-11 03:38:05

+2

它非常迅速/ fp。 – 2015-02-11 04:00:13

+0

謝謝,這更優雅。我一直在Objective C編程多年,並在Swift中參加iTunes U Stanford iOS編程課程。我仍然有很多要了解新範例。 – SSteve 2015-02-13 19:11:24

1

我知道什麼更簡潔開箱即用,但你可以很容易地實現前綴++,例如,

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

後,你可以用它來你的心臟的內容很簡潔:

str.substringFromIndex(++str.startIndex) 
6

這個怎麼樣?

s.removeAtIndex(s.startIndex) 

這當然假設你的字符串是可變的。它返回已被刪除的字符,但會改變原始字符串。

56

更新斯威夫特4

在斯威夫特4,String符合Collection再次,所以它可以使用dropFirstdropLast修剪字符串的開始和結束。其結果是Substring類型的,所以你需要傳遞給String構造函數來得到一個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)) // "" 

更新斯威夫特3

如果你只是想刪除的第一個字符並希望改變代替原來的字符串,然後看到@ MickMacCallum的答案。如果您想在此過程中創建新字符串,請使用substring(from:)。隨着擴展String,你可以隱藏的substring(from:)substring(to:)醜陋創造有益的補充修剪的開始和結束的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" 

dropFirstdropLast他們之前,這些功能會在出現AREN崩潰String中沒有足夠的字母。主叫方有責任正確使用它們。這是一個有效的設計決策。人們可以寫他們返回一個可選的,然後將不得不由調用者解開。


夫特2.x的

唉在夫特2dropFirstdropLast和(前一個最佳的解決方案)不是因爲他們以前一樣方便。隨着擴展String,你可以隱藏的substringFromIndexsubstringToIndex醜陋:

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" 

dropFirstdropLast他們之前,這些功能會崩潰如果沒有在字符串提供足夠的字母。主叫方有責任正確使用它們。這是一個有效的設計決策。人們可以寫他們返回一個可選的,然後將不得不由調用者解開。


In 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)) 
    } 
} 
+3

我仍然被斯威夫特內置的字符串操作複雜得多。我的意思是這是基本的,基本的東西;它不應該看起來像我正在實施一個解析器。感謝擴展來簡化這一點。令人費解的是,Apple不會僅僅將其添加到String類中!也許它仍然有很大的不確定性。 – devios1 2016-02-22 21:57:48

+0

這就是他們所說的「進化」的孩子。如果我們不需要每天處理它,那就太好笑了。我知道String API是有原因的,但實際上,這必須推遲這麼多潛在的轉換。前面的評論者是絕對正確的 - 這應該是基本的,基本的東西。 – 2017-11-01 11:13:01

1

在夫特2使用此字符串延伸:

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

夫特2.2

'提前' 是不可用:調用 '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)) 
    } 

迅速4

的字符串的內容的圖作爲字符的集合。

@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 "" 
} 
+1

我想你忘了將否定-count添加到chopSuffix函數中 – 2016-06-30 04:10:05

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

要刪除從字符串第一個字符

let choppedString = String(txtField.text!.characters.dropFirst()) 
+0

@JasonFoglia我不知道你是否放棄投票。如果你放棄投票,你可否請詳細解釋。 – 2017-03-29 10:44:13

+0

我重新檢查了這一點,發現它是正確的。我編輯了答案,以便我可以正確地投票。 – 2017-04-01 16:54:22

0

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

這裏是一個Swift4崩潰中保存chopPrefix擴展的版本,並chopSuffix向社會...

extension String { 
    func chopPrefix(_ count: Int = 1) -> String { 
     return count>self.count ? self : String(self[index(self.startIndex, offsetBy: count)...]) 
    } 
} 
0

以前的答案是相當不錯的,但由於今天,我想這可能是去除從字符串的第一個字符斯威夫特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 ... 
相關問題