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.
![](../../users/profiles/1187415.webp)
- 488,667
- 78
- 1,132
- 1,248
![](../../users/profiles/945711.webp)
- 2,929
- 3
- 16
- 21
6 Answers
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]
![](../../users/profiles/1187415.webp)
- 488,667
- 78
- 1,132
- 1,248
-
4As a side note, `let array = Array(someSet)` also works in Swift 2 – Suragch Jul 23 '15 at 05:07
-
... or let myArray = myNSSet.allObjects as! [mySpecificType] – angelos.p Dec 13 '15 at 11:17
-
3@plusangel: Yes, if an `NSSet` is given. The question was about a Swift `Set`. – Martin R Dec 13 '15 at 11:25
-
@KendallHelmstetterGelner: I have double-checked the above code example with both Swift 2.3 and Swift 3. It compiled and worked as expected for me. What error do you get? – Martin R Oct 25 '16 at 05:19
-
@MartinR Interesting, I was trying it with a set from an NSManagedObject relationship, and it did not like the Array constructor at the time - now that I try to reproduce the problem though, I cannot. I do have to add the "arrayLiteral:" label into the Array constructor though. I removed my previous comment so it doesn't confuse anyone, thanks for checking! I don't know why the Swift guide does not have this conversion form... – Kendall Helmstetter Gelner Oct 26 '16 at 03:52
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]
![](../../users/profiles/1966109.webp)
- 76,586
- 23
- 234
- 201
-
Using one of this methods I can make optional array from optional set. – zalogatomek Jan 04 '17 at 17:10
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
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
![](../../users/profiles/4253437.webp)
- 30,010
- 12
- 103
- 113
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 }
}
![](../../users/profiles/6330.webp)
- 73,251
- 26
- 123
- 148
-
`myItemSet.sorted()` requires that the elements are `Comparable`. – `myItemSet.map { $0 }` should produce the same result as `Array(myItemSet)`, both create an array by enumerating all elements of the set. The latter still works for me, some details on your above comment would be appreciated. – Martin R Oct 25 '16 at 19:03
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))
![](../../users/profiles/4995948.webp)
- 913
- 7
- 25