Help us understand the problem. What is going on with this article?

swift4.0でランダムに取得した値の重複をなくす

はじめに

randomで値を取ってきても、重複して困るってこと結構ありませんか?

なんのために必要か?

自分はテニスが好きで、スクールに通ったり、地域のテニスイベントに参加したりしている。スクールはさておき、テニスイベントでは最後に参加者をランダムでダブルスの試合をするのだが、参加者が多いと、ダブルスのペアを考えるのが大変😩

そこで、手軽に持ち運びのできるiPhoneでそういったアプリを乱数を使って作れば、かなり需要があるんじゃねと思い作り始めました。

ぶつかった壁

乱数を取ってペアを作ること自体は簡単でした。
実際、このようなソースでランダムに4人取ることができます。

func makeDouble(Num:Int) {
        var intArray: [Int]
        intArray = []
        var intset: [Int]
        intset = []

        if Num < 4 {
            displayAlert()
        }else{
            intArray = []
            for i in 1...Num{
                intArray.append(i)
            }
            //
            for _ in 0..<4{
                let j = Int(arc4random_uniform(UInt32(intArray.count)))
                intset.append(intArray[j])

            }
        }
    }

これだとどういった問題が出てくるのかと言うと、重複(同じ数が複数回出てきてしまう。)問題が発生するのだ。
実際、このソースで動かしてみると結果は以下のようになる

[4, 10, 9, 1]
[4, 6, 9, 8]
[6, 4, 10, 10]
[8, 9, 4, 10]
[1, 7, 3, 7]
[9, 6, 1, 1]
[9, 5, 8, 5]
[6, 4, 3, 6]
[3, 10, 2, 6]
[1, 10, 8, 1]

10人でシャッフルした場合は重複が少ないように見えるが、これが5人だった場合には

[2, 3, 5, 1]
[2, 4, 4, 3]
[2, 3, 5, 2]
[2, 5, 1, 4]
[5, 2, 5, 1]
[1, 3, 4, 3]
[3, 3, 4, 5]
[5, 2, 3, 5]
[4, 5, 1, 2]
[4, 2, 5, 2]

とかなりの確率で重複した値が出てきてしまう。

じゃあどうするか?

巷では、重複をチェックするのに2重ループを回して重複の有無をチェックするやり方が
ちらほらと見受けられるが、もっとスマートにやりたい。

と色々試行錯誤してある方法を思いついた。

配列に値を入れてそこからランダムに値を入れて、それを配列から削除すれば、重複なくなるんじゃねと

実際に書いたソースがこちら

func makeDouble(Num:Int) {
        var intArray: [Int]
        intArray = []
        var intset: [Int]
        intset = []

        if Num < 4 {
            displayAlert()
        }else{
            intArray = []
            for i in 1...Num{
                intArray.append(i)
            }
            //
            for _ in 0..<4{
                let j = Int(arc4random_uniform(UInt32(intArray.count)))
                intset.append(intArray[j])
                intArray.remove(at: j)
            }
        }
    }

実際に重複した値が出てこないかチェックする。
先ほどと同じく5人、10人でチェックする(試行回数は10回)

[8, 7, 2, 10]
[5, 3, 10, 9]
[10, 4, 5, 1]
[1, 8, 4, 3]
[10, 4, 2, 7]
[6, 8, 2, 3]
[10, 6, 8, 2]
[3, 10, 7, 8]
[1, 9, 3, 7]
[8, 7, 4, 2]
[5, 1, 4, 3]
[2, 1, 3, 4]
[2, 5, 3, 4]
[1, 5, 3, 2]
[1, 2, 5, 3]
[2, 1, 5, 4]
[3, 5, 4, 1]
[1, 4, 3, 2]
[5, 4, 1, 2]
[4, 3, 5, 1]

これで重複は無くなった。(数字に偏りはあるが😅)

今回作ったアプリはこちらで公開してます。
https://github.com/tnatsume/ShuffleDoubles

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした