Swift Auf Array setzen

185

An NSSetkann in Arrayusing konvertiert werden, set.allObjects()aber es gibt keine solche Methode in der neuen Set(eingeführt mit Swift 1.2). Dies kann weiterhin durch Konvertieren von Swift Set in NSSet und Verwenden der allObjects()Methode erfolgen, dies ist jedoch nicht optimal.

Gebratener Reis
quelle

Antworten:

350

Sie können ein Array mit allen Elementen aus einem bestimmten Swift Seteinfach mit erstellen

let array = Array(someSet)

Dies funktioniert, weil Setes dem SequenceTypeProtokoll entspricht und Arraymit einer Sequenz initialisiert werden kann. Beispiel:

let mySet = Set(["a", "b", "a"])  // Set<String>
let myArray = Array(mySet)        // Array<String>
print(myArray) // [b, a]
Martin R.
quelle
4
Als Randnotiz, let array = Array(someSet)funktioniert auch in Swift 2
Suragch
... oder lassen Sie myArray = myNSSet.allObjects als! [mySpecificType]
angelos.p
3
@plusangel: Ja, wenn ein NSSetgegeben ist. Die Frage war über einen Swift Set.
Martin R
@KendallHelmstetterGelner: Ich habe das obige Codebeispiel sowohl mit Swift 2.3 als auch mit Swift 3 überprüft. Es wurde wie erwartet kompiliert und funktioniert. Welchen Fehler bekommen Sie?
Martin R
@MartinR Interessanterweise habe ich es mit einem Satz aus einer NSManagedObject-Beziehung versucht, und der Array-Konstruktor hat mir damals nicht gefallen - jetzt, wo ich versuche, das Problem zu reproduzieren, kann ich es nicht. Ich muss jedoch die Bezeichnung "arrayLiteral:" in den Array-Konstruktor einfügen. Ich habe meinen vorherigen Kommentar entfernt, damit er niemanden verwirrt, danke für die Überprüfung! Ich weiß nicht, warum der Swift-Leitfaden dieses Umrechnungsformular nicht hat ...
Kendall Helmstetter Gelner
21

Im einfachsten Fall , mit Swift 3, können Sie Array‚s init(_:)initializer bekommen ein Arrayvon einem Set. init(_:)hat die folgende Erklärung:

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

Erstellt ein Array mit den Elementen einer Sequenz.

Verwendung:

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

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

Allerdings , wenn Sie auch auf jedem Element einige Operationen ausführen möchten Ihrer Setwährend Umwandlung in ein Array, können Sie verwenden map, flatMap, sort, filterund andere funktionelle Methoden bereitgestellt CollectionProtokoll:

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
quelle
Mit einer dieser Methoden kann ich ein optionales Array aus einem optionalen Satz erstellen.
Tzaloga
11

ZUSATZ:

Swift hat keine DEFINED ORDER für Set und Dictionary. Aus diesem Grund sollten Sie die sorted () -Methode verwenden, um zu verhindern, dass unerwartete Ergebnisse wie Ihr Array wie ["a", "b"] oder ["b", "a" angezeigt werden "] und du willst das nicht.

Um dies zu beheben:

FÜR SETS

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

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

Ohne sortiert ()

Es kann sein:

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

einfache Mathematik: 3! = 6


quelle
10

Ich habe eine einfache Erweiterung , die Ihnen eine unsortierte gibt Arrayals Eigenschaft Setin Swift 4.0 .

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

Wenn Sie ein sortiertes Array wünschen, können Sie entweder eine zusätzliche berechnete Eigenschaft hinzufügen oder die vorhandene an Ihre Anforderungen anpassen.

Um dies zu nutzen, rufen Sie einfach an

let array = set.array
CodeBender
quelle
3

Die aktuelle Antwort für Swift 2.x und höher (aus dem Swift Programming Language-Handbuch zu Sammlungstypen) scheint darin zu bestehen, entweder die Set-Einträge wie folgt zu durchlaufen:

for item in myItemSet {
   ...
}

Oder um die "sortierte" Methode zu verwenden:

let itemsArray = myItemSet.sorted()

Es scheint, dass die Swift-Designer allObjects als Zugriffsmechanismus nicht mochten, da Sets nicht wirklich geordnet sind. Deshalb wollten sie sicherstellen, dass Sie kein Array ohne explizite Reihenfolge herausbekommen.

Wenn Sie den Aufwand für das Sortieren nicht möchten und sich nicht um die Reihenfolge kümmern, verwende ich normalerweise die Map- oder FlatMap-Methoden, die etwas schneller sein sollten, um ein Array zu extrahieren:

let itemsArray = myItemSet.map { $0 }

Mit diesem Array können Sie Folgendes tun: Wenn Sie ein Array eines bestimmten Typs benötigen (z. B. Berechtigungen aus einer Reihe verwalteter Objektbeziehungen, die nicht als typisierte Menge deklariert sind), können Sie Folgendes tun:

var itemsArray : [MyObjectType] = []
if let typedSet = myItemSet as? Set<MyObjectType> {
 itemsArray = typedSet.map { $0 }
}
Kendall Helmstetter Gelner
quelle
myItemSet.sorted()erfordert, dass die Elemente sind Comparable. - myItemSet.map { $0 }sollte das gleiche Ergebnis liefern wie Array(myItemSet), beide erstellen ein Array, indem sie alle Elemente der Menge auflisten. Letzteres funktioniert immer noch für mich, einige Details zu Ihrem obigen Kommentar wären willkommen.
Martin R
-2

Rufen Sie diese Methode auf und übergeben Sie Ihr Set

func getArrayFromSet(set:NSSet)-> NSArray {

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

So was :

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
print(self.getArrayFromSet(letters))
Shubham Bairagi
quelle
2
Array verwenden (<Set>) ist eine bessere Wahl
Sébastien REMY