Использование arc4random для генерации десяти случайных чисел

Я использую arc4random для генерации 10 случайных чисел, поэтому я могу затем запросить firebase, чтобы получить вопросы, содержащие случайно сгенерированные числа. Проблема в том, что я не хочу, чтобы какое-либо число появлялось более одного раза, чтобы не было повторяющихся вопросов. Текущий код ниже...

import UIKit
import Firebase

class QuestionViewController: UIViewController {

    var amountOfQuestions: UInt32 = 40

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        // Use a for loop to get 10 questions
        for _ in 1...10{
            // generate a random number between 1 and the amount of questions you have
            let randomNumber = Int(arc4random_uniform(amountOfQuestions - 1)) + 1
            print(randomNumber)
            // The reference to your questions in firebase (this is an example from firebase itself)
            let ref = Firebase(url: "https://test.firebaseio.com/questions")
            // Order the questions on their value and get the one that has the random value
            ref.queryOrderedByChild("value").queryEqualToValue(randomNumber)
                .observeEventType(.ChildAdded, withBlock: {
                    snapshot in
                    // Do something with the question
                    print(snapshot.key)
                })
        }
    }

    @IBAction func truepressed(sender: AnyObject) {
    }

    @IBAction func falsePressed(sender: AnyObject) {
    }
}

person Tom Fox    schedule 22.02.2016    source источник
comment
Вы не должны вычитать 1 из суммы вопросов.   -  person Leo Dabus    schedule 23.02.2016
comment
Вы можете случайным образом удалить каждый элемент из исходного массива, если не хотите, чтобы они повторялись дважды.   -  person Leo Dabus    schedule 23.02.2016


Ответы (5)


Учитывая общее количество вопросов

let questionsCount = 100

вы можете сгенерировать последовательность целых чисел

var naturals = [Int](0..<questionsCount)

Теперь, учитывая количество уникальных случайных чисел, которые вам нужны

let randomsCount = 10

это, конечно, не должно превышать общее количество вопросов

assert(randomsCount <= questionsCount)

вы можете создать свой список уникальных целых чисел

let uniqueRandoms = (1..<randomsCount).map { _ -> Int in
    let index = Int(arc4random_uniform(UInt32(naturals.count)))
    return naturals.removeAtIndex(index)
}
person Luca Angeletti    schedule 22.02.2016
comment
Поскольку вы не удаляете случайные объекты из массива, нельзя ли повторить одно и то же значение? Мне кажется, строку return naturals[index] следует заменить на return naturals.removeAtIndex(index). Это удалит и вернет объект. - person Duncan C; 23.02.2016
comment
@appzYourLife, как уже отметил Дункан С., не предотвратит появление случайного числа более одного раза. Просто измените количество вопросов на 10, и вы это заметите. - person Leo Dabus; 23.02.2016
comment
Ты прав! Позвольте мне исправить это, как только я вернусь домой. И благодарю вас! - person Luca Angeletti; 23.02.2016
comment
Исправлено через айфон. Еще раз спасибо. - person Luca Angeletti; 23.02.2016

У вас может быть массив для хранения значения, которое вы хотите рандомизировать, в вашем случае [1,2,3.... 10], а затем использовать arc4random для получения случайного индекса любого значения внутри (0..9 ), получить значение и удалить его из массива. Тогда вы никогда не получите одно и то же число из массива.

person Terence    schedule 22.02.2016

В качестве альтернативы генерации случайного числа на клиенте и запросу вопроса по указанному номеру вы можете загрузить весь массив вопросов и перетасовать массив. GameKit предоставляет встроенный метод для перемешивания массива.

import GameKit

// ...

let ref = Firebase(url: "https://test.firebaseio.com/questions")
// Order the questions on their value and get the one that has the random value
ref.queryOrderedByChild("value")
    .observeEventType(.ChildAdded, withBlock: {
        snapshot in
        // Shuffle your array
        let shuffledQuestions = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(snapshot)
        // Store your array somewhere and iterate through it for the duration of your game
    })
person JAL    schedule 22.02.2016

Вы можете генерировать случайные числа и хранить каждое число в файле NSArray. Однако, когда вы добавляете его в массив, вы можете проверить, содержит ли уже этот номер этот массив.

Например:

for _ in 1...10 {
let amountOfQuestions: UInt32 = 40
var intArray: [Int] = []
let randomNumber = Int(arc4random_uniform(amountOfQuestions - 1)) + 1

if intArray.contains(randomNumber) {

    repeat {
        randomNumber = Int(arc4random_uniform(amountOfQuestions - 1)) + 1
    } while intArray.contains(randomNumber)

    if !intArray.contains(randomNumber) {
        intArray.append(randomNumber)
    }


} else {
    intArray.append(randomNumber)
}

    print(intArray)
}

После этого вы можете сделать запрос FireBase с уникальными сгенерированными целыми числами. Надеюсь, я смог помочь :).

person Harish    schedule 22.02.2016

Создать несортированный массив из десяти случайных Int 0..99

var set = Set<Int>()
while set.count < 10 {
    let num = Int(arc4random_uniform(100))
    set.insert(num)
}
let arr = Array(set)
person dogsgod    schedule 23.02.2016