Search code examples
linuxswiftmacosfoundationnsset

NSSet(array: myArray) works on OS X but crashes in Ubuntu


The following code works in a Playground on OS X but doesn't work once compiled in Ubuntu using Swift.org.


In a Playground

This works as expected:

let permutedHands = [["A♦", "A♣", "6♠", "3♦", "T♥"], ["A♣", "A♦", "6♠", "3♦", "T♥"], ["6♠", "A♦", "A♣", "3♦", "T♥"], ["A♦", "6♠", "A♣", "3♦", "T♥"], ["T♥", "6♠", "A♦", "3♦", "A♣"], ["6♠", "T♥", "A♦", "3♦", "A♣"], ["A♦", "T♥", "6♠", "3♦", "A♣"], ["T♥", "A♦", "6♠", "3♦", "A♣"], ["6♠", "A♦", "T♥", "3♦", "A♣"], ["A♦", "6♠", "T♥", "3♦", "A♣"], ["3♦", "6♠", "A♦", "T♥", "A♣"], ["6♠", "3♦", "A♦", "T♥", "A♣"], ["A♦", "3♦", "6♠", "T♥", "A♣"], ["3♦", "A♦", "6♠", "T♥", "A♣"], ["6♠", "A♦", "3♦", "T♥", "A♣"], ["A♦", "6♠", "3♦", "T♥", "A♣"], ["3♦", "T♥", "A♦", "6♠", "A♣"], ["T♥", "3♦", "A♦", "6♠", "A♣"], ["A♦", "3♦", "T♥", "6♠", "A♣"], ["3♦", "A♦", "T♥", "6♠", "A♣"], ["T♥", "A♦", "3♦", "6♠", "A♣"], ["A♦", "T♥", "3♦", "6♠", "A♣"], ["3♦", "T♥", "6♠", "A♦", "A♣"], ["T♥", "3♦", "6♠", "A♦", "A♣"], ["6♠", "3♦", "T♥", "A♦", "A♣"], ["3♦", "6♠", "T♥", "A♦", "A♣"], ["T♥", "6♠", "3♦", "A♦", "A♣"], ["6♠", "T♥", "3♦", "A♦", "A♣"]]

let sortedPerms = permutedHands.map { $0.sort() }
let permSet = NSSet(array: sortedPerms)
let arr = Array(permSet) // [["3♦", "6♠", "A♣", "A♦", "T♥"]]

With swift build for Swift.org in Linux

Error message at compilation:

cannot convert value of type '[[String]]' to expected argument type '[AnyObject]'
let permSetArray = NSSet(array: sortedPerms)

I tried this in desperation, just in case:

let sortedPerms = perms.map { $0.sort() }.map { $0 as! AnyObject }

It makes the compiler happy but then it crashes at runtime:

Could not cast value of type 'Swift.Array' (0x7f84701950d8) to 'Swift.AnyObject' (0x7f84701700e8).
Aborted (core dumped)

I've skimmed through the Swift GitHub repositories but didn't find anything unimplemented or incomplete about NSSet, it looks ok in Swift.org's Foundation (as far as I can tell).

Any idea how to debug and fix this? A workaround could be also acceptable.


Solution

  • I didn't try Swift on Linux yet, but you can use this 'pure' Swift solution without import Foundation:

    let permutedHands = [["A♦", "A♣", "6♠", "3♦", "T♥"], ["A♣", "A♦", "6♠", "3♦", "T♥"], ["6♠", "A♦", "A♣", "3♦", "T♥"], ["A♦", "6♠", "A♣", "3♦", "T♥"], ["T♥", "6♠", "A♦", "3♦", "A♣"], ["6♠", "T♥", "A♦", "3♦", "A♣"], ["A♦", "T♥", "6♠", "3♦", "A♣"], ["T♥", "A♦", "6♠", "3♦", "A♣"], ["6♠", "A♦", "T♥", "3♦", "A♣"], ["A♦", "6♠", "T♥", "3♦", "A♣"], ["3♦", "6♠", "A♦", "T♥", "A♣"], ["6♠", "3♦", "A♦", "T♥", "A♣"], ["A♦", "3♦", "6♠", "T♥", "A♣"], ["3♦", "A♦", "6♠", "T♥", "A♣"], ["6♠", "A♦", "3♦", "T♥", "A♣"], ["A♦", "6♠", "3♦", "T♥", "A♣"], ["3♦", "T♥", "A♦", "6♠", "A♣"], ["T♥", "3♦", "A♦", "6♠", "A♣"], ["A♦", "3♦", "T♥", "6♠", "A♣"], ["3♦", "A♦", "T♥", "6♠", "A♣"], ["T♥", "A♦", "3♦", "6♠", "A♣"], ["A♦", "T♥", "3♦", "6♠", "A♣"], ["3♦", "T♥", "6♠", "A♦", "A♣"], ["T♥", "3♦", "6♠", "A♦", "A♣"], ["6♠", "3♦", "T♥", "A♦", "A♣"], ["3♦", "6♠", "T♥", "A♦", "A♣"], ["T♥", "6♠", "3♦", "A♦", "A♣"], ["6♠", "T♥", "3♦", "A♦", "A♣"]]
    
    let sortedPerms = permutedHands.map { $0.sort() }
    var arr: Array<Array<String>> = []
    sortedPerms.forEach { (a) -> () in
        let contains = arr.contains{ $0 == a }
        if !contains {
            arr.append(a)
        }
    }
    print(arr) // [["3♦", "6♠", "A♣", "A♦", "T♥"]]