LoginSignup
12
6

More than 5 years have passed since last update.

Swift 3 で Array を Shuffle

Posted at

Array を Shuffle したい

Swift である事を実装しようと思うと、ある別の事を実装しなくてはならなくて、その実装をしようと思ったら、さらに別の実装が必要となった。それが、Array をシャッフルする事でした。そんなの標準であってもよさそうですが、標準のライブラリにはなく、どこかの勉強会で発表を見た気もするが、記憶の切れ端が見つかりません。検索して、良さげのを見つけてきても、Swift 3.0 でビルドエラーになったり、どこかのブログのコードスニペットを使ってみると、クラッシュして調べてみると、中で swap を使っている所でクラッシュしていました。いろいろ調査するよりも、自分で作ってしまえと思いこの記事を書きます。

設計方針は、「多少非効率であっても、swap を使わない」としました。

Array+shuffled.swift
extension Array {

    func shuffled() -> [Element] {
        var results = [Element]()
        var indexes = (0 ..< count).map { $0 }
        while indexes.count > 0 {
            let indexOfIndexes = Int(arc4random_uniform(UInt32(indexes.count)))
            let index = indexes[indexOfIndexes]
            results.append(self[index])
            indexes.remove(at: indexOfIndexes)
        }
        return results
    }

}

簡単な説明をすると、n番目の要素を表す 0 から n-1までの整数を生成して 中間的なArray を作ります。その中間的なArrayから要素一個をランダムに選び(mとする)、元のArrayの m 番目の要素を新しいArrayに追加し、中間的なArrayから、mを表す要素を削除し、これを最後まで繰り返せば、非破壊的にシャッフルされた Array が出来上がります。

もっと効率的な...なんて一瞬脳裏を横切りましたが、ここはエネルギーをかける所ではないのでこれでよしとする事にします。コード自体よりこの記事を書く方が時間がかかった事は秘密

Gist

コードは gist からも入手できます。

参考資料

How do I shuffle an array in Swift?
swiftでシャッフル関数

環境に関する表示

Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
12
6
6

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
12
6