Dizionario rapido: ottieni valori come array


151

Ho un dizionario contenente UIColor gli oggetti hash da un valore enum, ColorScheme:

var colorsForColorScheme: [ColorScheme : UIColor] = ...

Vorrei essere in grado di estrarre una matrice di tutti i colori (i valori) contenuti in questo dizionario. Pensavo di poter usare ilvalues proprietà, così come viene usata per scorrere i valori del dizionario ( for value in dictionary.values {...}), ma questo restituisce un errore:

let colors: [UIColor] = colorsForColorSchemes.values
                        ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
'LazyBidrectionalCollection<MapCollectionView<Dictionary<ColorScheme, UIColor>, UIColor>>' is not convertible to 'UIColor'

Sembra che anziché restituire un Arrayvalore, il valuesmetodo restituisce un tipo di raccolta più astratto. C'è un modo per ottenere un Arraycontenente i valori del dizionario senza estrarli in afor-in ciclo?


1
Swift 5: colorsForColorSchemes.values
Juan Boero,

Risposte:


285

A partire da Swift 2.0, Dictionaryla valuesproprietà di ora restituisce a LazyMapCollectionanziché a LazyBidirectionalCollection. Il Arraytipo sa come inizializzarsi usando questo tipo di raccolta astratta:

let colors = Array(colorsForColorSchemes.values)

L'inferenza di tipo di Swift sa già che questi valori sono UIColoroggetti, quindi non è richiesto il cast del tipo, il che è bello!


1
puoi anche lanciarlo come un array con oggetti digitati. funziona alla grande! thanks let colors = [CustomColorObject] (colorsForColorSchemes.values)
bolnad

6
Sembra che in Swift 2.0, Dictionary.values ​​ora restituisca un LazyMapCollection anziché un LazyBidirectionalCollection. Sfortunatamente, .array non è definito su un LazyMapCollection. Tuttavia, il modo Array (dizionario.valori) funziona ancora bene poiché i tipi di array sanno come inizializzarsi da un LazyMapCollection.
Tod Cunningham,

8
Si noti che l'ordine dei valori potrebbe essere imprevisto. Ad esempio [0: "small", 1: "medium", 2: "large"], probabilmente NON genererà["small", "medium", "large"]
Simon Bengtsson il

55

È possibile mappare il dizionario su una matrice di valori:

let colors = colorsForColorScheme.map { $0.1 }

La chiusura prende una tupla chiave-valore dal dizionario e restituisce solo un valore. Pertanto, la funzione mappa produce una matrice di valori.

Versione più leggibile dello stesso codice:

let colors = colorsForColorScheme.map { (scheme, color) in
    return color
}

AGGIORNARE

Da Xcode 9.0, è possibile accedere ai valori del dizionario utilizzando la valuesproprietà, conforme al Collectionprotocollo:

let colors = colorsForColorScheme.values

In genere lo vuoi solo come un array:

let colors = Array(dict.values)

e basta.


2
Ma in realtà questo è un modo leggibile per ottenere array let colors = Array (colorsForColorScheme.values)
Renetik

1
Adoro questa soluzione
Navy Seal,

@pjuzeliunas dato che questa è la risposta migliore qui, ho appena modificato l'ultima del 2020. Ovviamente rilassati, modifica ecc! grazie e grazie!
Fattie


8

puoi creare un'estensione su LazyMapCollection

public extension LazyMapCollection  {

    func toArray() -> [Element]{
        return Array(self)
    }
}

colorsForColorSchemes.values.toArray() o colorsForColorSchemes.keys.toArray()


3

Innanzitutto, dalla seguente affermazione, sembra che il nome della tua variabile (dizionario) sia colorsForColorScheme

var colorsForColorScheme: [ColorScheme : UIColor] = ... 

mentre stai cercando di ottenere i valori dal colorsForColorSchemesdizionario quando hai fatto-

let colors: [UIColor] = colorsForColorSchemes.values

che dovrebbe darti un errore di compilazione. Comunque presumo che tu abbia avuto un refuso, e il nome del tuo dizionario è colorsForColorSchemes. Quindi, ecco la soluzione

Come accennato in precedenza, a causa della proprietà di inferenza del tipo in swift, il codice può dedurre che il tipo restituito dalla .valuesfunzione restituisce una matrice di UIColor. Tuttavia, Swift vuole essere sicuro per i tipi, quindi quando si memorizzano i valori colorsnell'array, è necessario definirlo esplicitamente. Per Swift 5 e versioni successive, ora puoi semplicemente fare-

let colors = [UIColor](colorsForColorSchemes.values)

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.