生成随机字符串而不进行随机播放和重复之前的字符串?

时间:2017-09-23 17:14:38

标签: arrays swift string random

当我按下按钮时,我的代码已经生成了一个随机的数组String,但有时会重复一个String。我需要做什么才能使String" Mango"只有在没有使用shuffle的情况下调用所有其他字符串时才会再次调用,我想一次调用一个字符串?

示例:" Mango"," Kiwi"," Banana"," Pineapple"," Melon", " Mango"," Kiwi",.....

这是我的代码:

var array = ["Mango", "Banana", "Apple","Kiwi", "Melon", "Pineapple"]

let fruits = Int(arc4random_uniform(UInt32(array.count)))

print(array[fruits])

3 个答案:

答案 0 :(得分:0)

您需要实现一些逻辑。如果你想得更努力,这很容易。在您的Playground中运行它,或者如果您完全理解这段代码,您可以在项目中执行此操作。

var array = ["Mango", "Banana", "Apple","Kiwi", "Melon", "Pineapple"]
var selectedIndices = [Int]()

for _ in 1...20 {

    let randomFruitIndex = Int(arc4random_uniform(UInt32(array.count)))

    // Print only if not yet printed once

    if !selectedIndices.contains(randomFruitIndex) {
        print(array[randomFruitIndex])
        selectedIndices.append(randomFruitIndex)
    }

    // Reset

    if selectedIndices.count == array.count {
        print("----- CLEARING SELECTED INDICES----")
        selectedIndices.removeAll()
    }
}

正如您所看到的,我们将每个生成的随机数(在您的情况下,它是fruits变量。)添加到Int数组中。然后,如果selectedIndices的数量等于水果array的数量,请清除所有存储的selectedIndices

输出:

Pineapple
Melon
Mango
Kiwi
Banana
Apple
----- CLEARING SELECTED INDICES----
Mango
Melon

答案 1 :(得分:0)

这是对我评论中链接主题的接受答案的改编:

var source = ["Mango", "Banana", "Apple","Kiwi", "Melon", "Pineapple"]
var usedElements = [String]()

func choosePseudoRandomElement() -> String {
    if source.count == 0 {
        source = usedElements
        usedElements = []
    }

    let randomIndex = Int(arc4random_uniform(UInt32(source.count)))
    let randomItem = source[randomIndex]
    usedElements.append(randomItem)
    source.remove(at: randomIndex)

    return randomItem
}

for _ in 1...18 {
    print("Item: \(choosePseudoRandomElement())")
}

此解决方案的一个潜在问题是可能发生,一次完整迭代的最后一个元素也作为第二次迭代的第一个元素出现。您可以通过将随机选择的项目与之前选择的项目进行比较来处理该情况(使用while循环直到项目不再匹配)。 此外,这确实从源数组中删除元素。如果您不想这样,请创建源数组的副本。

答案 2 :(得分:0)

为了避免重复,您需要跟踪以前看过的水果。有几种方法可以做到这一点,所有提议的解决方案都以这种或那种方式做到这一点。

对于您的特定用例,您需要将此跟踪保留在按钮执行的代码之外(例如,在视图控制器中)。

这是一个可以帮助解决此问题的通用结构: (您可以在视图控制器中定义它,如果这是一次性的事情,或者如果您打算在其他地方重用该机制,则在其外部)

struct RandomItems
{
   var items : [String]
   var seen  = 0

   init(_ items:[String])
   { self.items = items }

   mutating func next() -> String
   {
     let index = Int(arc4random_uniform(UInt32(items.count - seen)))
     let item  = items.remove(at:index)
     items.append(item)
     seen = (seen + 1) % items.count
     return item
   }
}

要使用它,您将声明一个变量(在您的VC中),以跟踪您的成果:

var fruits = RandomItems(["Mango", "Banana", "Apple","Kiwi", "Melon", "Pineapple"])

在按钮的代码中使用该变量(fruits)在每次执行时打印非重复的水果名称

func buttonPressed() // <- use your function here
{
    print( fruits.next() )
}