0

How can I not repeat the array when I click on the button in swift? I'm trying to generate fruits without them repeating.

import UIKit

class fruitrandomViewController: UIViewController {
@IBOutlet weak var nextfruitButton: UIButton!
@IBOutlet weak var fruitbox: UILabel!

@IBAction func fruitbutton(_ sender: UIButton) {

    let array = ["Apple","Banana","Orange","Pinapple", "Plum", "Pear",]


    let randomFruitgenerator = Int(arc4random_uniform(UInt32(array.count)))
    fruitbox.text = array[randomFruitgenerator]

    }
}

4 Answers4

1

My suggestion is to use a Set and remove the random item from the set

var set = Set(["Apple","Banana","Orange","Pinapple", "Plum", "Pear"])

@IBAction func fruitbutton(_ sender: UIButton) {
    if let fruit = set.randomElement() {
        fruitbox.text = fruit
        set.remove(fruit)
    } else {
        fruitbox.text = "" // or whatever to indicate that the set is empty
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
0

My suggest:

You can random each item 1 time

let originFruits = ["Apple","Banana","Orange","Pinapple", "Plum", "Pear"]
let array = originFruits

@IBAction func fruitbutton(_ sender: UIButton) {
...
 let fruitRandom = array random
 array delete fruitRandom 
  if (array empty) {
    array = originFruits
  }
}

You can check and remove in next time

let originFruits = ["Apple","Banana","Orange","Pinapple", "Plum", "Pear"]
let array = originFruits
let skipFruit = ""

@IBAction func fruitbutton(_ sender: UIButton) {
...
 array = originFruits
 array delete skipFruit
 let fruitRandom = array random
 skipFruit = fruitRandom
}
JackDao
  • 433
  • 4
  • 10
  • Thank you! But this is still repeating some of the fruits. I am trying to avoid any sort of repetition. – confusedcoder Mar 06 '20 at 05:38
  • Hmm. when you clicking on button. How you doing it? click very quick? Multiple click? So you can disable button for handle set fruit string after done you can enable button again. In case time block to sort and array not updated before next random you can block button about 500 millisecond or more for 1 clicking. – JackDao Mar 06 '20 at 06:30
  • just click the button once. It's constantly enabled. The use case should be that when I click "Next Fruit" button the next fruit should show on a label. – confusedcoder Mar 06 '20 at 17:13
0

I think this will work, but I think it's Time Complexity can be O(n) as I am assuming that there is a possibility of randomElement return Apple every time and savedFruit is also Apple, so in that case, the Time Complexity will be O(n). A better workaround will be to remove that element from that array so, the next time the randomElement will be different for sure. Then, once it is different you can append the old one and remove the current one. I hope it makes sense to you, but for now this will work I think:

let array = ["Apple","Banana","Orange","Pinapple", "Plum", "Pear"]
var savedFruit = String()

func fetchRandomFruit()  {

if let fruit = array.randomElement() {

    if fruit != savedFruit  { //Here it will check if the last element is same as the new randomElement
        savedFruit = fruit
        fruitbox.text = savedFruit
     } else {
       fetchRandomFruit()
    }  
  }
}


@IBAction func fruitbutton(_ sender: UIButton) {

  fetchRandomFruit()
}
Rob
  • 2,086
  • 18
  • 25
  • Thank you! But this is still repeating some of the fruits. I am trying to avoid any sort of repetition. – confusedcoder Mar 06 '20 at 05:38
  • How can I sort the string that way it runs through all the fruits one by one. It doesn't have to be randomized. I just want each word to show only once when I click the button. – confusedcoder Mar 06 '20 at 05:40
  • That is a different question, your question stated not repeating. Update your question and I will update my answer, or better you can post a new question. – Rob Mar 06 '20 at 05:45
-2

Use fruitbox.text = array.randomElement() ?? "default value for if array is empty". This is not guaranteed not to repeat, but is random.

If you want to ensure it does not repeat, use this

var new = array.randomElement() ?? fruitbox.text
while new == fruitbox.text {
    new = array.randomElement() ?? fruitbox.text
}
fruitbox.text = new

This WILL loop infinitely (until it crashes) if the array is empty.

Sam
  • 2,350
  • 1
  • 11
  • 22
  • `This is not guaranteed not to repeat, but is random. ` well, the op did ask for non-repeating random. – Shamas S Mar 06 '20 at 02:33
  • @ShamasS-ReinstateMonica That is why I provided a solution that did address that interpretation of their problem. The other potential way to read it is that the random functionality was not working, so I also addressed that. – Sam Mar 06 '20 at 03:02
  • 1
    Thank you! But this is still repeating some of the fruits. I am trying to avoid any sort of repetition. – confusedcoder Mar 06 '20 at 05:38