0

I have made an array of UIImagesViews and I have made a code to assign them random pictures. I would like to make an if-statement if more than or 5 pictures have the same picture shown.

var images: [UIImageView] = [Image1, Image2, Image3, Image4, Image5, Image6, Image7, Image8, Image9]

The different pictures are named card1, card2, card3

let firstRandomNumber = arc4random_uniform(3) + 1
    let firstRandomString:String = String(format: "card%i", firstRandomNumber)

    self.Image1.image = UIImage(named: firstRandomString)

    let secondRandomNumber = arc4random_uniform(3) + 1
    let secondRandomString:String = String(format: "card%i", secondRandomNumber)

    self.Image2.image = UIImage(named: secondRandomString)

All images have their own specific code like the ones above. Now, as I said, I would like to make an if-statement or switch-case if five or more of the Images have the same picture shown.

Edit: Here is the updated code;

let imageNames:NSArray = [firstRandomString, secondRandomString, thirdRandomString, fourthRandomString, fifthRandomString, sixthRandomString, seventhRandomString, eighthRandomString, ninthRandomString]

    let maxRepeating = imageNames
        .map {img in imageNames.reduce(0) { $1 == img ? $0 + 1 : $0} }
        .reduce(0){ $1 > $0 ? $1 : $0 }

The code only has one error at .map {img in imageNames.reduce(0) { $1 == img ? $0 + 1 : $0} } saying;

Binary operator '==' cannot be applied to two 'Element' (aka 'AnyObject') operands

Edit: Here is another code I have tried from Christopher Kevin;

var correct = 0

func checkImageDuplication() {
        let imageArray : NSArray = [firstRandomString, secondRandomString, thirdRandomString, fourthRandomString, fifthRandomString, sixthRandomString, seventhRandomString, eighthRandomString, ninthRandomString]
        let imageDataArray = imageArray.map { (image) -> NSData in
            return UIImagePNGRepresentation(image as! UIImage)!
        }

        let countSet = NSCountedSet(array: imageDataArray)
        for imageData in imageDataArray {
            let count = countSet.countForObject(imageData)
            if count > 5 {
                correct = 5
            }
        }
    }

@IBAction func PlayerPRESSED(sender: AnyObject) {
    if correct == 5 {
        view.backgroundColor = UIColor.greenColor()
    }
}

I tried the code but it will not execute the action. (view.backgroundColor) Anyone have any Idea what is wrong with this code?

R.S
  • 253
  • 2
  • 7

2 Answers2

0

Your logic here needs to be separated from the views.

Create a model in the same class that holds an array of UIImage. Use this array to populate your cards, and to check whether more than 5 images are the same. Example untested and unoptimised code:

var images = [UIImage]() 

private func populateImages() {
  // Fill images array, and perhaps populate imageViews
}

private func checkImageDuplication() {
  let imageDataArray = imageArray.map { (image) -> NSData in
    return UIImagePNGRepresentation(image)!
  }

  let countSet = NSCountedSet(array: imageDataArray)
  for imageData in imageDataArray {
      let count = countSet.countForObject(imageData)
      if count > 5 {
          // Handle here
      }
  }
}
  • Seems like a great answer, but what and which Swift filter's can I use and how? :) – R.S Jan 06 '16 at 16:32
  • In hindsight, a model of `UIImage` might make things more difficult, simply because they cannot easily be compared without turning them into pure NSData representations. If your model was instead an array of String's (value types, so they can be compared directly), you could use `NSCountedSet` to get all of the counts. Simply add to the NSCountedSet the image name string's in the `populateImages()` function, and then iterate through all of the counts in `checkImageDuplication()`. – Christopher Kevin Howell Jan 06 '16 at 16:39
  • That means I have to make a different string name for all 9 images with all three different types of pictures? – R.S Jan 06 '16 at 16:47
  • You don't have to use strings if it doesn't make sense. You can use UIImage, but you'll have to populate the `NSCountedSet` with NSData objects instead. This is a better model but more verbose to type out for an answer :) (for how to convert UIImage to data for comparison, see http://stackoverflow.com/questions/11342897/how-to-compare-two-uiimage-objects) – Christopher Kevin Howell Jan 06 '16 at 16:49
  • I can not use this code in ViewController, and I can not ctrl-drag the images to another created file (swift file). How I am supposed to create the image array? :-) – R.S Jan 06 '16 at 18:04
  • @ChristopherKevinHowell Look at the code in the update! :-) – R.S Jan 06 '16 at 19:27
  • @Cristik Yeh this definitely isn't optimised for performance! More so readability. – Christopher Kevin Howell Jan 06 '16 at 20:57
0

I don't think you can compare UIImage objects, as each call to UIImage(named:) will generate another UIImage instance, even if the name is the same. I'd recommend generating an array of strings, and testing that array for repetitions, with something like this:

let maxRepeating = imageNames
    .map {img in imageNames.reduce(0) {  $1 == img ? $0 + 1 : $0} }
    .reduce(0){ $1 > $0 ? $1 : $0 }
Cristik
  • 30,989
  • 25
  • 91
  • 127
  • How do I create these strings? (imageNames?) - or should I use the strings `Image1`? – R.S Jan 06 '16 at 18:33
  • The strings in discussion are the ones passed to UIImage(named:), – Cristik Jan 06 '16 at 18:45
  • Look at the updated question and see if I have done it right and how I can get rid of the error? :) If so, you have answered the question! :) – R.S Jan 06 '16 at 19:10
  • @R.S StackOverflow doesn't work like this, with users adding more and more to the question. I answered your original question, if you have another one, please post a separate question. – Cristik Jan 06 '16 at 19:25
  • Since your code is not working and will not execute the if-statement, your answer is not complete. – R.S Jan 06 '16 at 21:39
  • I'm sorry if your expectations were for someone else to write code for you. You're on the wrong site if you expect this. – Cristik Jan 06 '16 at 21:41