はじめに
以前swift2で実装していたものをswift3.0に移植するにあたり、ちょっとハマった、修正履歴として残しておこうと思う。
以前の記事はこちら>swift2 で 固定長分割
前置き
なぜこんな実装が必要なのというのに対して、特に回答する予定はありません、諸般の事情でとだけ
参考にしたページ
結局エラーメッセージが一番参考になるのですが、そのメッセージをもとに、どのように直すかという部分で参考にしています。
- swift migration guid
- apple-api-reference: stride function
- apple-api-reference: string function
- blog: ranges
- blog: strings
変わった部分
短いコードの割に変わった部分が結構ありました。
- stride
- advancedBy
- joinWithSeparator
stride
これは、stride(to)が無くなっていて、stride(from
by:)に置き換える必要がありました。
swift:String+Splitter.swift 0.stride(to: limit, by: len).forEach {
これが、以下のようになりました。
swift:String+Splitter.swift stride(from: 0, to: limit, by: len).forEach {
advancedBy
indexで頑張ります
joinWithSeparator
joined(separator:)に変わりました。
とりあえず、コードを載せます
extension String {
/** 文字列を固定長で分割する
- Parameter len: 分割する長さ
- Parameter handle: 分割ごとに呼び出される
*/
public func Splitter(_ len: Int, handle: ((_ cut: String, _ isLast: Bool)->())) {
{
let limit = self.characters.count
stride(from: 0, to: limit, by: len).forEach {
p in
guard let st = self.index(startIndex,offsetBy:p, limitedBy: endIndex)
else {
handle("",true)
return
}
guard let end = self.index(st, offsetBy: len, limitedBy: endIndex)
else {
let cut = self.substring(from: st)
handle(cut,true)
return
}
let cut = self.substring(with: st..<end)
handle(cut, end == endIndex)
}
}
}
書き直し
以前のコードより実行時間が遅くなってしまいました、以前のコードにできるだけ似せてみます。
/** 文字列を固定長で分割する
- Parameter len: 分割する長さ
- Parameter handle: 分割ごとに呼び出される
*/
public func Splitter(len: Int, handle: ((_ cut: String, _ isLast: Bool)->())) {
let array = self.characters.map { String($0) }
let limit = self.characters.count
stride(from: 0, to: limit, by: len).forEach {
p in
guard let st = array.index(array.startIndex,offsetBy:p, limitedBy: array.endIndex)
else {
handle("",true)
return
}
guard let end = array.index(st, offsetBy: len, limitedBy: array.endIndex)
else {
let cut = array[st..<array.endIndex].joined()
handle(cut,true)
return
}
let cut = array[st..<end].joined()
handle(cut, end == array.endIndex)
}
}
これにより、以前より高速に動作するようになりました。arrayが頻出しているのが気にくわないけど。。。
substringより、分解してjoinedした方が早いのは、swiftの内部実装のせいかな。