SwiftでN文字ずつに分割した文字列を得る方法
移転しました →
例えば"hogefugapiyo"
という文字列があるとして、これを4文字ずつに分割するなら["hoge", "fuga", "piyo"]
、5文字ずつに分割するなら["hogef", "ugapi", "yo"]
を得たい。
Rubyであればscanメソッドを使って次のように実行できるということがわかった。
str = "hogefugapiyo" # => "hogefugapiyo" str.scan(/.{1,5}/) # => ["hogef", "ugapi", "yo"]
参考
これと同じことをSwiftでやりたくなったが、どうやら全く同じようなことをする関数はなさそうに見えた。なのでSwift力が足りないながらも自前で書いてみたのでそれを晒してみる。
Rubyの用にArrayを返す関数を追加するのでもよかったが、SequenceTypeを使うほうがよさそうな気がしたので↓のように実装した。String
にsubstr(Int)
という関数を生やして、それを呼ぶとforループやmapとかが使えるという感じになった。
extension String { var length: Int { return count(self) } internal class SubstringGenerator: GeneratorType { typealias Element = String let count: Int let string: String var i = 0 init(count: Int, string: String) { if count <= 0 { fatalError("'count' must be bigger than 0.") } self.count = count self.string = string } func next() -> Element? { if i < string.length { var endIndex : String.Index if i + count > string.length { endIndex = string.endIndex } else { endIndex = advance(string.startIndex, i + count) } var range = advance(string.startIndex, i)..<endIndex i += count return string.substringWithRange(range) } else { return nil } } } internal class SubstringSequence : SequenceType { let count: Int let string : String typealias Generator = SubstringGenerator init(count: Int, string: String) { self.count = count self.string = string } func generate() -> Generator { return Generator(count: count, string: string) } } func substr(count: Int) -> SubstringSequence { return SubstringSequence(count: count, string: self) } }
このsubstr
を実際に使ってみるとこうなる。
for substr in "hogefugapiyo".substr(5) { println(substr) } // hogef // ugapi // yo var array = map("hogefugapiyo".substr(5)) {$0} println(array) // [hogef, ugapi, yo]
どうですかね、これ。

- 作者: 荻原剛志
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2014/12/10
- メディア: 大型本
- この商品を含むブログ (2件) を見る