从数组列表中随机选择5个元素,而不重复元素

时间:2017-07-16 18:30:19

标签: arrays swift random swift3

我目前正在尝试为iOS制作应用,但我无法获得一些简单的代码。基本上我需要从数组列表中随机选择5个元素而不重复元素。我有一个草稿,但它只显示一个元素。

这是我的代码:

let array1 = ["salmon", "turkey", "salad", "curry", "sushi", "pizza"]

let randomIndex1 = Int(arc4random_uniform(UInt32(array1.count)))

print(array1[randomIndex1])

5 个答案:

答案 0 :(得分:7)

你可以这样做:

let array1 = ["salmon", "turkey", "salad", "curry", "sushi", "pizza", "curry", "sushi", "pizza"]
var resultSet = Set<String>()

while resultSet.count < 5 {
    let randomIndex = Int(arc4random_uniform(UInt32(array1.count)))
    resultSet.insert(array1[randomIndex])
}

let resultArray = Array(resultSet)

print(resultArray)

set只能包含唯一元素,因此不能多次使用相同的元素。

我创建了一个空set,然后只要数组包含少于5个元素(您选择的数字),我就迭代并向set添加一个随机元素。

在最后一步中,我们需要将集合转换为数组以获取所需的数组。

答案 1 :(得分:1)

SWIFT 5.1

已经回答了这个问题,但是我敢于提出一个更简单的解决方案。

如果采用数组并将其转换为Set,则将具有不按特定顺序排列的唯一项数组。然后,如果您从该数组中选取5个元素,您将得到相同的结果。

但这只是2行;)

示例:

["B", "G", "H", "E", "C"]

打印示例:

        Sheets("conf_9").Columns(5).Copy Destination:=Sheets("Rec_9").Columns(9)
        Sheets("conf_9").Columns(6).Copy Destination:=Sheets("Rec_9").Columns(10)
        Sheets("conf_9").Columns(7).Copy Destination:=Sheets("Rec_9").Columns(7)
        Sheets("conf_9").Columns(8).Copy Destination:=Sheets("Rec_9").Columns(8)
        Sheets("conf_9").Columns(12).Copy Destination:=Sheets("Rec_9").Columns(6)

仅要求您的对象必须符合Hashable协议。大多数标准Swift类型都可以使用,否则使自己的类型符合通常很简单。

https://developer.apple.com/documentation/swift/hashable

答案 2 :(得分:0)

var array1 = ["salmon", "turkey", "salad", "curry", "sushi", "pizza"]

while array1.count > 0 {

    // random key from array
    let arrayKey = Int(arc4random_uniform(UInt32(array1.count)))

    // your random number
    let randNum = array1[arrayKey] 

    // make sure the number ins't repeated
    array1.removeAtIndex(arrayKey)
}

通过从数组中删除已挑选的值,可以防止选择重复项

答案 3 :(得分:0)

就是我的¢2: Moe Abdul-Hameed的解决方案有一个理论上的缺点:如果你在每次迭代中滚动相同的randomIndexwhile循环将永远不会退出。这与tho非常不同。

另一种方法是创建原始数组的可变副本,然后排除拾取的项目:

var source = array1
var dest = [String]()
for _ in 1...5 {
    let randomIndex = Int(arc4random_uniform(UInt32(source.count)))
    dest.append(source[randomIndex])
    source.remove(at: randomIndex)
}

print(dest)

答案 4 :(得分:0)

如果您不关心更改原始数组,下面的代码会将拾取的元素放在数组的末尾,然后它将返回数组的最后一部分作为切片。 如果您不关心更改原始数组,这很有用,优点是它不使用额外的内存,您可以在同一个数组上多次调用它。

extension Array {
    mutating func takeRandomly(numberOfElements n: Int) -> ArraySlice<Element> {
        assert(n <= self.count)
        for i in stride(from: self.count - 1, to: self.count - n - 1, by: -1) {
            let randomIndex = Int(arc4random_uniform(UInt32(i + 1)))
            self.swapAt(i, randomIndex)
        }
        return self.suffix(n)
    }
}

示例:

var array = [1,2,3,4]
let a1 = array.takeRandomly(numberOfElements: 2)
let a2 = array.takeRandomly(numberOfElements: 2)