Swift Set to Array

ArraysSwiftSet

Arrays Problem Overview


An NSSet can be converted to Array using set.allObjects() but there is no such method in the new Set (introduced with Swift 1.2). It can still be done by converting Swift Set to NSSet and use the allObjects() method but that is not optimal.

Arrays Solutions


Solution 1 - Arrays

You can create an array with all elements from a given Swift Set simply with

let array = Array(someSet)

This works because Set conforms to the SequenceType protocol and an Array can be initialized with a sequence. Example:

let mySet = Set(["a", "b", "a"])  // Set<String>
let myArray = Array(mySet)        // Array<String>
print(myArray) // [b, a]

Solution 2 - Arrays

In the simplest case, with Swift 3, you can use Array's init(_:) initializer to get an Array from a Set. init(_:) has the following declaration:

init<S>(_ s: S) where S : Sequence, Element == S.Iterator.Element

>Creates an array containing the elements of a sequence.

Usage:

let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy")    
let stringArray = Array(stringSet)

print(stringArray)
// may print ["toy", "car", "bike", "boat"]

However, if you also want to perform some operations on each element of your Set while transforming it into an Array, you can use map, flatMap, sort, filter and other functional methods provided by Collection protocol:

let stringSet = Set(["car", "boat", "bike", "toy"])
let stringArray = stringSet.sorted()

print(stringArray)
// will print ["bike", "boat", "car", "toy"]

let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy") 
let stringArray = stringSet.filter { $0.characters.first != "b" }

print(stringArray)
// may print ["car", "toy"]

let intSet = Set([1, 3, 5, 2]) 
let stringArray = intSet.flatMap { String($0) }

print(stringArray)
// may print ["5", "2", "3", "1"]

let intSet = Set([1, 3, 5, 2])
// alternative to `let intArray = Array(intSet)`
let intArray = intSet.map { $0 }

print(intArray)
// may print [5, 2, 3, 1]

Solution 3 - Arrays

I created a simple extension that gives you an unsorted Array as a property of Set in Swift 4.0.

extension Set {
    var array: [Element] {
        return Array(self)
    }
}

If you want a sorted array, you can either add an additional computed property, or modify the existing one to suit your needs.

To use this, just call

let array = set.array

Solution 4 - Arrays

ADDITION :

Swift has no DEFINED ORDER for Set and Dictionary.For that reason you should use sorted() method to prevent from getting unexpected results such as your array can be like ["a","b"] or ["b","a"] and you do not want this.

TO FIX THIS:

FOR SETS

var example:Set = ["a","b","c"]
let makeExampleArray = [example.sorted()]
makeExampleArray 

Result: ["a","b","c"]

Without sorted()

It can be:

["a","b","c"] or ["b","c","a",] or ["c","a","b"] or ["a","c","b"] or ["b","a","c"] or ["c","b","a"] 

simple math : 3! = 6

Solution 5 - Arrays

The current answer for Swift 2.x and higher (from the Swift Programming Language guide on Collection Types) seems to be to either iterate over the Set entries like so:

for item in myItemSet {
   ...
}

Or, to use the "sorted" method:

let itemsArray = myItemSet.sorted()

It seems the Swift designers did not like allObjects as an access mechanism because Sets aren't really ordered, so they wanted to make sure you didn't get out an array without an explicit ordering applied.

If you don't want the overhead of sorting and don't care about the order, I usually use the map or flatMap methods which should be a bit quicker to extract an array:

let itemsArray = myItemSet.map { $0 }

Which will build an array of the type the Set holds, if you need it to be an array of a specific type (say, entitles from a set of managed object relations that are not declared as a typed set) you can do something like:

var itemsArray : [MyObjectType] = []
if let typedSet = myItemSet as? Set<MyObjectType> {
 itemsArray = typedSet.map { $0 }
}

Solution 6 - Arrays

call this method and pass your set

func getArrayFromSet(set:NSSet)-> NSArray {

return set.map ({ String($0) })
}

Like This :

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
print(self.getArrayFromSet(letters))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFried RiceView Question on Stackoverflow
Solution 1 - ArraysMartin RView Answer on Stackoverflow
Solution 2 - ArraysImanou PetitView Answer on Stackoverflow
Solution 3 - ArraysCodeBenderView Answer on Stackoverflow
Solution 4 - Arraysuser7206023View Answer on Stackoverflow
Solution 5 - ArraysKendall Helmstetter GelnerView Answer on Stackoverflow
Solution 6 - ArraysShubham bairagiView Answer on Stackoverflow