从Swift数组中随机选择一个项目而不重复

问题描述:

此代码从预设颜色数组中选择一种随机颜色。我如何制作它,以便不会多次挑选相同的颜色?

This code picks a random color from a array of pre-set colors. How do I make it so the same color doesn't get picked more than once?

var colorArray = [(UIColor.redColor(), "red"), (UIColor.greenColor(), "green"), (UIColor.blueColor(), "blue"), (UIColor.yellowColor(), "yellow"), (UIColor.orangeColor(), "orange"), (UIColor.lightGrayColor(), "grey")]

var random = { () -> Int in
    return Int(arc4random_uniform(UInt32(colorArray.count)))
} // makes random number, you can make it more reusable


var (sourceColor, sourceName) = (colorArray[random()])


创建索引数组。从数组中删除其中一个索引,然后使用它来获取颜色。

Create an array of indexes. Remove one of the indexes from the array and then use that to fetch a color.

这样的事情:

var colorArray = [
  (UIColor.redColor(), "red"), 
  (UIColor.greenColor(), "green"), 
  (UIColor.blueColor(), "blue"), 
  (UIColor.yellowColor(), "yellow"), 
  (UIColor.orangeColor(), "orange"), 
  (UIColor.lightGrayColor(), "grey")]

var indexes = [Int]();

func randomItem() -> UIColor
{
  if indexes.count == 0
  {
    print("Filling indexes array")
    indexes = Array(0..< colorArray.count)
  }
  let randomIndex = Int(arc4random_uniform(UInt32(indexes.count)))
  let anIndex = indexes.removeAtIndex(randomIndex)
  return colorArray[anIndex].0;
}

上面的代码创建一个数组索引。函数 randomItem 查看索引是否为空。如果是,则用索引值填充它,范围从0到 colorArray.count - 1

The code above creates an array indexes. The function randomItem looks to see if indexes is empty. if it is, it populates it with index values ranging from 0 to colorArray.count - 1.

然后选择索引数组中的随机索引,删除索引数组中该索引处的值,并将其用于从 colorArray 中获取并返回一个对象。 (它不会从 colorArray 中删除​​对象。它使用间接,并从indicesArray中删除对象,indexArray最初包含 colorArray 。

It then picks a random index in the indexes array, removes the value at that index in the indexes array, and uses it to fetch and return an object from your colorArray. (It doesn't remove objects from the colorArray. It uses indirection, and removes objects from the indexesArray, which initially contains an index value for each entry in your colorArray.

上面的一个缺陷是,从indexArray中获取最后一项后,用全套填充它索引,你从新重新填充的数组得到的下一个颜色可能与你得到的最后一个颜色相同。

The one flaw in the above is that after you fetch the last item from indexArray, you populate it with a full set of indexes, and it's possible that the next color you get from the newly repopulated array will be the same as the last one you got.

可以添加额外的逻辑防止这种情况。

It's possible to add extra logic to prevent this.