現在重複しないランダムな値を表示する機能を実装しているのですが、抽出後に重複チェックするのではなく抽出した値をその場でランダムの選択肢から削除する方法を探しております。
検索しても見つからなかったので、何か良い方法を知っていたら教えてください。
Swift
1randomNum = Int.random(in: 1...50)
1が出たら(in: 2...50)になるようなイメージです。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
出た数の状態を管理しないといけないため、配列変数を使うのが良いかと思います。いくつか方法があると思いますけれど、たとえば構造体を使って作ってみるのはいかがでしょう。
swift
1struct Random { 2 3 /// 乱数のリストを配列のインスタンスで管理します。 4 private(set) var numbers: Array<Int> 5 6 /// 値の列を使ってインスタンスを生成します。 7 /// - Parameter numbers: 乱数リストです。 8 init<S>(numbers: S) where S: Sequence, S.Element == Int { 9 10 self.numbers = Array(numbers) 11 } 12 13 /// 乱数用の配列から、ランダムで1つ取得します。 14 /// - Returns: ランダムで値をひとつ返します。値が出尽くしたときは `nil` を返します。 15 mutating func number() -> Int? { 16 17 // 乱数配列のインデックスをランダムで抽出します。 18 guard let index = numbers.indices.randomElement() else { 19 20 // 乱数配列が空だった場合は `nil` を返します。 21 return nil 22 } 23 24 // 全ての処理が終わった後で、乱数配列から今回使ったインデックスの値を削除するように処理を予約します。 25 defer { 26 numbers.remove(at: index) 27 } 28 29 // ランダムでピックアップしたインデックスが指す値を返します。 30 return numbers[index] 31 } 32}
このような構造体を作ると、次のようにして重複しない乱数を得ることができました。
swift
1 2var random = Random(numbers: 1 ... 50) 3 4while let number = random.number() { 5 6 print("乱数:", number, ", 残り:", random.numbers) 7}
投稿2020/05/29 09:18
編集2020/05/29 09:19総合スコア441
0
おそらくもう一つの方法です。
1...50
で初期化された配列を用意し、要素をシャッフルしたあと、頭から順番に値を取り出しています。
ただし、この方法だと配列の残り数をご自身で管理する必要があるため、使い回しや安全性を考えるとTomohiroKumagaiが提案された構造体を作る方法の方がいいかと思います。
Swift
1import UIKit 2 3var num = [Int](1...50) 4print("最初の値: ", num) 5 6// 要素をシャッフルする 7num.shuffle() 8print("シャッフル後: ", num) 9 10repeat { 11 // 配列の最初の要素だけ取り出し、配列から削除 12 let dropped = num.removeFirst() 13 print("(dropped)", terminator: ", ") 14} while num.count > 0 15 16//最初の値: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50] 17//シャッフル後: [36, 14, 48, 22, 33, 38, 18, 6, 13, 25, 8, 16, 21, 44, 40, 34, 49, 45, 17, 37, 47, 31, 50, 39, 4, 30, 35, 3, 7, 20, 10, 43, 23, 26, 28, 24, 15, 42, 12, 41, 5, 29, 2, 19, 9, 11, 32, 1, 46, 27] 18//36, 14, 48, 22, 33, 38, 18, 6, 13, 25, 8, 16, 21, 44, 40, 34, 49, 45, 17, 37, 47, 31, 50, 39, 4, 30, 35, 3, 7, 20, 10, 43, 23, 26, 28, 24, 15, 42, 12, 41, 5, 29, 2, 19, 9, 11, 32, 1, 46, 27,
投稿2020/05/29 10:05
総合スコア5086
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/29 10:23
2020/06/01 02:19
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/29 10:24
2020/06/01 02:18