0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

用 Swift 實作隔幾個字插入某個字串

Posted at

以信用卡卡號來舉例

4242424242424242

每隔四個數字插入一個空白,像是這樣:

4242 4242 4242 4242

實作

原先有嘗試過用 map 或是 reduce 等等高階函式的方式實作,
但是在建置時間和型別推論的時間都太長,再來是必須要反覆取得記憶體空間,不是很有智慧(笑)。
於是就去找了一下有沒有比較「環保」的做法。

接著就在 Stack Overflow 找到一個解法 (這裡),
這個解法簡單來說,是從 String 「內部」 來修改它的內容,這樣可以在不用額外索取記憶體空間的情形下達成。

簡化這個解答到必要的程式碼之後如下:

extension StringProtocol where Self: RangeReplaceableCollection {
    mutating func insert(separator: Self, every count: Int) {
        for index in indices.reversed() where index != startIndex &&
            distance(from: startIndex, to: index) % count == 0 {
                insert(contentsOf: separator, at: index)
        }
    }
}

詳細原理的解說可以參照 Swift Blog 的這篇文章

走訪每一個字元並以指定間隔插入指定字串

在這裡就用我自己的話說明看看。

因為 Swift 的 String 無法以單純的整數定位,所以必須要使用 String.Index
在這邊就是透過 Collection protocol 提供的 indices 來走訪每個位置。

(RangeReplaceableCollection 有繼承 Collection protocol)

先反轉再走訪的原因是可以避免在插入字串的過程中,長度改變造成 index 不好計算的問題

for index in indices.reversed()

觸發條件就是當前的 index 還沒抵達 startIndex :

index != startIndex

以及與第一個字元的距離的餘數為 0

distance(from: startIndex, to: index) % count == 0

符合條件之後,就可以用 RangeReplaceableCollection 提供的方法,來在指定位置插入指定字串

insert(contentsOf: separator, at: index)
  • RangeReplaceableCollection#insert(contentsOf:at:) - 文件

使用方法

var cardNumber = "4242424242424242"
cardNumber.insert(separator: " ", every: 4)
print(cardNumber) // output: 4242 4242 4242 4242

當然也可以拿來插入複數字元:

var content = "鯛魚燒"
content.insert(separator: " 🐟 ", every: 1)
print(content) // output: 鯛 🐟 魚 🐟 燒

以上!

參考資料

環境

  • Xcode 10.3 (10G8)
  • Swift 5

最後

如果內文需要更新、有錯誤或容易誤解的地方,歡迎發修改或是留言告訴我!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?