Swift Set to Array

187

NSSetMożna przekształcić w Arrayużyciu set.allObjects(), ale nie istnieje metoda, w nowej Set(wprowadzone szybkimi 1.2). Nadal można to zrobić, konwertując Swift Set na NSSet i używając allObjects()metody, ale nie jest to optymalne.

Smażony ryż
źródło

Odpowiedzi:

352

Możesz utworzyć tablicę ze wszystkimi elementami z danego Swift Setpo prostu za pomocą

let array = Array(someSet)

Działa to, ponieważ Setjest zgodne z SequenceTypeprotokołem i Arraymożna go zainicjować sekwencją. Przykład:

let mySet = Set(["a", "b", "a"])  // Set<String>
let myArray = Array(mySet)        // Array<String>
print(myArray) // [b, a]
Martin R.
źródło
4
Na marginesie, let array = Array(someSet)działa również w Swift 2
Suragch
... lub pozwól myArray = myNSSet.allObjects as! [mySpecificType]
angelos.p
3
@plusangel: Tak, jeśli NSSetpodano. Pytanie dotyczyło Szybkiego Set.
Martin R
@KendallHelmstetterGelner: Sprawdziłem dwukrotnie powyższy przykład kodu w Swift 2.3 i Swift 3. Skompilowałem i działałem zgodnie z oczekiwaniami. Jaki masz błąd?
Martin R
@MartinR Ciekawe, próbowałem go z zestawem relacji NSManagedObject i nie podobało mi się wówczas konstruktor Array - teraz, gdy próbuję odtworzyć problem, nie mogę. Muszę jednak dodać etykietę „arrayLiteral:” do konstruktora Array. Usunąłem mój poprzedni komentarz, aby nikogo nie mylić, dziękuję za sprawdzenie! Nie wiem, dlaczego przewodnik Swift nie ma tej formy konwersji ...
Kendall Helmstetter Gelner,
21

W najprostszym przypadku , ze Swift 3, można użyć Array„s init(_:)inicjator dostać Arrayz punktu A Set. init(_:)ma następującą deklarację:

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

Tworzy tablicę zawierającą elementy sekwencji.

Stosowanie:

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

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

Jednakże , jeśli chcesz, aby wykonać pewne operacje na każdego elementu Setpodczas przekształcania go w produkt Array, można użyć map, flatMap, sort, filteri inne metody funkcjonalne świadczone przez Collectionprotokół:

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]
Imanou Petit
źródło
Za pomocą jednej z tych metod mogę wykonać opcjonalną tablicę z opcjonalnego zestawu.
tzaloga
11

DODATEK:

Swift nie ma DEFINIOWANEGO ZAMÓWIENIA dla Seta i Dictionary. Z tego powodu powinieneś użyć metody sorted (), aby zapobiec otrzymywaniu nieoczekiwanych wyników, takich jak tablica może być jak [„a”, „b”] lub [„b”, ​​„a „] i nie chcesz tego.

ABY NAPRAWIĆ TO:

DLA ZESTAWÓW

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

Wynik: [„a”, „b”, „c”]

Bez sortowania ()

To może być:

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

prosta matematyka: 3! = 6


źródło
10

Stworzyłem proste rozszerzenie, które daje nieposortowane Arrayjako właściwość Setw Swift 4.0 .

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

Jeśli chcesz posortować tablicę, możesz dodać dodatkową właściwość obliczoną lub zmodyfikować istniejącą według własnych potrzeb.

Aby z tego skorzystać, wystarczy zadzwonić

let array = set.array
CodeBender
źródło
3

Obecna odpowiedź dla Swift 2.x i nowszych (z przewodnika Swift Programming Language na temat rodzajów kolekcji) wydaje się polegać na iteracji po wpisach Set w następujący sposób:

for item in myItemSet {
   ...
}

Lub, aby użyć metody „posortowanej”:

let itemsArray = myItemSet.sorted()

Wygląda na to, że projektanci Swift nie lubili allObjects jako mechanizmu dostępu, ponieważ zestawy nie są tak naprawdę uporządkowane, więc chcieli się upewnić, że nie wyjdzie z tablicy bez zastosowania jawnego uporządkowania.

Jeśli nie chcesz narzucać sortowania i nie przejmujesz się kolejnością, zwykle używam metod map lub flatMap, które powinny być nieco szybsze do wyodrębnienia tablicy:

let itemsArray = myItemSet.map { $0 }

Który zbuduje tablicę typu, który posiada Zestaw, jeśli potrzebujesz, aby była tablicą określonego typu (powiedzmy, że uprawnia z zestawu relacji zarządzanych obiektów, które nie są zadeklarowane jako zbiór typowy), możesz zrobić coś takiego:

var itemsArray : [MyObjectType] = []
if let typedSet = myItemSet as? Set<MyObjectType> {
 itemsArray = typedSet.map { $0 }
}
Kendall Helmstetter Gelner
źródło
myItemSet.sorted()wymaga, aby elementy były Comparable. - myItemSet.map { $0 }powinien dać ten sam wynik, ponieważ Array(myItemSet)oba tworzą tablicę, wyliczając wszystkie elementy zestawu. To drugie nadal działa dla mnie, niektóre szczegóły dotyczące powyższego komentarza będą mile widziane.
Martin R
-2

wywołaj tę metodę i przekaż swój zestaw

func getArrayFromSet(set:NSSet)-> NSArray {

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

Lubię to :

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
print(self.getArrayFromSet(letters))
Shubham Bairagi
źródło
2
Use Array (<Set>) jest lepszym wyborem
Sébastien REMY