Grab 2 randomElements that are not the same? [dupl

2019-03-04 07:33发布

问题:

This question already has an answer here:

  • Get random elements from array in Swift 5 answers

I am trying to grab 2 random values that are not the same in a string like this

    var players = ["Jack, John, Michael, Peter"]
    var playersArray = ["\(players.randomElement) and \(players.randomElement) has to battle")

How am i to do this, so it grabs 2 different values?

回答1:

A while back I created a class RandomObjects that maintained an array of objects and could be used to serve up random, non-repeating objects from the array one at a time. It works by maintaining an array of indexes and removing an index from the indexes array until it's depleted.

It even has a provision to "refill" the indexes after all the values have been returned, and logic to avoid the same value from being returned after the indexes array is refilled.

It was written in Swift 2, but I just updated it to Swift 4 and posted it to GitHub:

https://github.com/DuncanMC/RandomObjects.git

The class is defined like this:

class RandomObjects<T> {
    var objectsArray: [T]
    var indexes: [Int]!
    var oldIndex: Int?

The key bit of code from that class is this function:

public func randomObject(refillWhenEmpty: Bool = true) -> T? {
    var randomIndex: Int
    var objectIndex: Int

    if refillWhenEmpty {
        fillIndexesArray()
    } else if indexes.isEmpty {
        return nil
    }
    repeat {
        randomIndex = Int(arc4random_uniform(UInt32(indexes.count)))
        objectIndex = indexes[randomIndex]
    } while objectIndex == oldIndex

    indexes.remove(at: randomIndex)

    oldIndex = objectIndex
    return objectsArray[objectIndex];
}

The check for objectIndex == oldIndex is only needed when you have gone through every object in the array and have just repopulated the indexes array. It makes sure you don't repeat the last entry.