Swift impostato su array


187

Un NSSetpuò essere convertito in Arrayutilizzo set.allObjects()ma non esiste un metodo simile nel nuovo Set(introdotto con Swift 1.2). Può ancora essere fatto convertendo Swift Set in NSSet e usando il allObjects()metodo, ma non è ottimale.

Risposte:


352

Puoi creare un array con tutti gli elementi di un dato Swift Setsemplicemente con

let array = Array(someSet)

Questo funziona perché è Setconforme al SequenceTypeprotocollo e Arraypuò essere inizializzato con una sequenza. Esempio:

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

4
Come nota let array = Array(someSet)a
margine

... oppure lascia che myArray = myNSSet.allObjects as! [mySpecificType]
angelos.p,

3
@plusangel: Sì, se NSSetviene fornito. La domanda riguardava uno Swift Set.
Martin R,

@KendallHelmstetterGelner: ho ricontrollato l'esempio di codice sopra con Swift 2.3 e Swift 3. Ha compilato e funzionato come previsto per me. Che errore ricevi?
Martin R,

@MartinR Interessante, lo stavo provando con un set da una relazione NSManagedObject, e al momento non mi piaceva il costruttore di array - ora che provo a riprodurre il problema, non posso. Devo aggiungere l'etichetta "arrayLiteral:" nel costruttore dell'array. Ho rimosso il mio commento precedente in modo da non confondere nessuno, grazie per il controllo! Non so perché la guida di Swift non abbia questo modulo di conversione ...
Kendall Helmstetter Gelner,

21

Nel caso più semplice , con Swift 3, puoi usare Arrayl' init(_:)inizializzatore per ottenere un Arrayda a Set. init(_:)ha la seguente dichiarazione:

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

Crea una matrice contenente gli elementi di una sequenza.

Uso:

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

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

Tuttavia , se anche si desidera eseguire alcune operazioni su ogni elemento della vostra Setmentre trasformandolo in un Array, è possibile utilizzare map, flatMap, sort, filtere altri metodi funzionali forniti da Collectionprotocollo:

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]

Usando uno di questi metodi posso creare un array opzionale da un set opzionale.
tzaloga,

11

AGGIUNTA:

Swift non ha DEFINED ORDER per Set e Dictionary.Per questo motivo dovresti usare il metodo sort () per evitare di ottenere risultati imprevisti come l'array può essere come ["a", "b"] o ["b", "a "] e non lo vuoi.

PER FISSARE QUESTO:

PER SET

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

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

Senza ordinamento ()

Può essere:

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

matematica semplice: 3! = 6


10

Ho creato una semplice estensione che ti Arrayda una proprietà non ordinata Setin Swift 4.0 .

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

Se si desidera un array ordinato, è possibile aggiungere una proprietà calcolata aggiuntiva o modificare quella esistente in base alle proprie esigenze.

Per usare questo, basta chiamare

let array = set.array

3

La risposta attuale per Swift 2.xe versioni successive (dalla guida al linguaggio di programmazione Swift sui tipi di raccolta) sembra essere quella di scorrere le voci Set in questo modo:

for item in myItemSet {
   ...
}

Oppure, per utilizzare il metodo "ordinato":

let itemsArray = myItemSet.sorted()

Sembra che ai progettisti di Swift non sia piaciuto allObjects come meccanismo di accesso perché i set non sono realmente ordinati, quindi volevano essere sicuri di non uscire da un array senza applicare un ordine esplicito.

Se non vuoi il sovraccarico dell'ordinamento e non ti preoccupi dell'ordine, di solito uso i metodi map o flatMap che dovrebbero essere un po 'più veloci per estrarre un array:

let itemsArray = myItemSet.map { $0 }

Che costruirà un array del tipo contenuto nel Set, se ne hai bisogno per essere un array di un tipo specifico (diciamo, dà diritto a un set di relazioni di oggetti gestiti che non sono dichiarate come set tipizzato) puoi fare qualcosa del tipo:

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

myItemSet.sorted()richiede che gli elementi lo siano Comparable. - myItemSet.map { $0 }dovrebbe produrre lo stesso risultato di Array(myItemSet), entrambi creano un array enumerando tutti gli elementi dell'insieme. Quest'ultimo funziona ancora per me, alcuni dettagli sul tuo commento sopra sarebbero apprezzati.
Martin R,

-2

chiama questo metodo e passa il tuo set

func getArrayFromSet(set:NSSet)-> NSArray {

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

Come questo :

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

2
Usa array (<Imposta>) è una scelta migliore
Sébastien REMY
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.