0

Trying to make and shuffle a card deck in Swift, made up of Card objects in an array called cardDeck. Then I want to shuffle it. Relevant code:

    var cardDeck = [card]()

    for ind in 1 ... 4  
    {
        for ind2 in 1 ... 13
        {
            cardDeck.append(card(number: ind2, color: ind))
        }
    }

    cardDeck = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(cardDeck)

"Cannot assign value of type [anyobject] to logic.card" ("logic" is the overall class name, and Card is another class within it)

Anyone know whats wrong? I guess the array is not an AnyObject type of array since I declared it as containing cards, right?

OhDannyBoy
  • 95
  • 8
  • What's `card`? A struct or a class? Although note that type names should start with a capital letter, i.e `Card`. – Hamish May 15 '16 at 15:08
  • Its a class. And oh, I didn't think about that. Is that just a best practice, or syntax relevant? – OhDannyBoy May 15 '16 at 15:09
  • Where exactly does the error occur? – luk2302 May 15 '16 at 15:09
  • On the deck shuffling line – OhDannyBoy May 15 '16 at 15:10
  • @OhDannyBoy The naming should be unrelated, it's just best practice. – Hamish May 15 '16 at 15:10
  • Yes, Im afraid it is. Strange stuff. – OhDannyBoy May 15 '16 at 15:15
  • Is there any other part of the code that could be relevant? I can't think of any though. The error says right there that its something about the array content type. – OhDannyBoy May 15 '16 at 15:21
  • Had a hard time getting all that code in an updated post, with the inlines messing up constantly, I hope a screenshot is okay. variable names are a little different, since they're translated in the original post, but you'll see the structure, and hopefully a mistake. :D http://imgur.com/vpirAHZ – OhDannyBoy May 15 '16 at 15:39

1 Answers1

1

The problem is that arrayByShufflingObjectsInArray takes an [AnyObject] and returns an [AnyObject].

Therefore its going to completely throw away your [Card] type information that you provide as an input, and thus give you an error about not being able to convert types when you try to assign the output back to your original array. I suspect this is due to the method being implemented in Objective-C, not Swift.

A more Swifty version of the method would look like this:

func arrayByShufflingObjectsInArray<T:AnyObject>(array:[T]) -> [T] {
    ...
}

Through using generics, you can preserve the type information that you pass in to begin with, returning the same type that you inputted. In fact, you can write your own extension of GKRandomSource in order to do just that:

extension GKRandomSource {
    func arrayOfSameTypeByShufflingObjectsInArray<T:AnyObject>(array:[T]) -> [T] {
        return arrayByShufflingObjectsInArray(array) as! [T]
    }
}

(Feel free to come up with a more catchy name for the method)

The force downcast is used as an ugly solution to the problem – which is why I recommend creating an extension, rather than using this directly. It cannot crash, as the output array is guaranteed to contain objects of the same type as the input (as the array you pass in can only contain a single type).

You can now use it like so:

cardDeck = GKRandomSource.sharedRandom().arrayOfSameTypeByShufflingObjectsInArray(cardDeck)
Hamish
  • 78,605
  • 19
  • 187
  • 280