【Swift】配列から一部分の抜いた時に返されるArraySliceについて

今日もちょっとした小ネタです。配列をRangeで一部分抜いた時にちょっとハマったことがあったので、ご紹介致します。

配列をRangeで抜くと返ってくるもの

以下の様に配列から一部分の抽出したくなるときってないでしょうか。

// 元の配列
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// 元の配列から一部分を抽出
let sub = array[3...5]

これ・・・arrayとsubって型が違うんですね。普通に考えて同じ型だろうと思っていました。が、arrayの型は'[Int]’で、subは’ArraySlice‘になるそうです。

実験

ちょっと実験をしてみました。先ずはほんとに違う型かどうか・・・

// Intの配列をprintする関数を定義
func printArray(_ array: [Int]) {
    array.forEach { (each) in
        print(each, terminator: "")
    }
    print("")
}

// 元の配列
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 元の配列から一部分を抽出
let sub = array[3...5]

printArray(array)
printArray(sub) // ここでコンパイルエラー
// Cannot convert value of type 'ArraySlice' to expected argument type '[Int]'

確かにprintArray関数にsubを渡そうとすると、上記のようなエラーになってコンパイルが通りませんでした。

どうしたら良いのか

これ・・・どうしましょうね。
とりあえず、元の'[Int]’に戻すことが出来れば、なんとかなりそうです。いくつか戻す方法を考えてみました。こんなんで良いんですかね〜。もっと良いやり方がありましたら教えて頂けるとありがたいです。

// Arrayのコンストラクタに突っ込む
printArray(Array(sub))
// 空の配列を足して配列にする
printArray(sub + [])
// フィルターで無条件に抽出
printArray(sub.filter({ (e) -> Bool in
    true
}))
// マップで抽出
printArray(sub.map({ (e) -> Int in
    e
}))
// 同じこと
printArray(sub.map{$0})
// リバースしてリバースする
printArray(sub.reversed().reversed())

う〜ん、なんだかな〜。2番目とか好きですね。javaでStringに変換かけてるソースとか見かけますね。それで良いのかって感じですが、でもなんか好き。誰か正しいやり方ご存知無いでしょうか? 

関連記事

【Mac】手っ取り早くUSBメモリからUEFI起動出来るUbuntuを作る

Invalid Binary?・・・アイコンはAsset Catalogを使いま...

SwiftでOpenALの簡単サンプルソース

【Raspberry Pi】Raspbian StretchからRaspbian...

【GraalVM】ちょっと弄ってみた

【Homebrew】使い方メモ