Kamus Swift: Dapatkan nilai sebagai array

150

Saya memiliki kamus yang berisi UIColorbenda-benda hash dengan nilai enum, ColorScheme:

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

Saya ingin dapat mengekstrak array dari semua warna (nilai-nilai) yang terkandung oleh kamus ini. Saya pikir saya bisa menggunakan valuesproperti, seperti yang digunakan saat iterasi nilai kamus ( for value in dictionary.values {...}), tetapi ini mengembalikan kesalahan:

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

Tampaknya daripada mengembalikan Arraynilai, valuesmetode mengembalikan tipe koleksi yang lebih abstrak. Apakah ada cara untuk mendapatkan Arraynilai kamus tanpa mengekstraknya dalam satu for-inlingkaran?

Stuart
sumber
1
Swift 5: colorsForColorSchemes.values
Juan Boero

Jawaban:

284

Pada Swift 2.0, Dictionary's valuesproperti sekarang mengembalikan LazyMapCollectionbukannya LazyBidirectionalCollection. The Arraytipe tahu bagaimana menginisialisasinya sendiri menggunakan jenis koleksi abstrak ini:

let colors = Array(colorsForColorSchemes.values)

Inferensi tipe Swift sudah tahu bahwa nilai-nilai ini adalah UIColorobjek, jadi tidak perlu casting tipe, yang bagus!

Stuart
sumber
1
Anda juga bisa melemparkannya sebagai array dengan objek yang diketik juga. bekerja hebat! terima kasih biarkan warna = [CustomColorObject] (colorsForColorSchemes.values)
bolnad
6
Sepertinya di Swift 2.0, Dictionary.values ​​sekarang mengembalikan LazyMapCollection sebagai kebalikan dari LazyBidirectionalCollection. Sayangnya, .array tidak didefinisikan pada LazyMapCollection. Namun, cara Array (dictionary.values) masih berfungsi dengan baik karena tipe array tahu bagaimana menginisialisasi dirinya dari LazyMapCollection.
Tod Cunningham
8
Perhatikan bahwa urutan nilai mungkin tidak terduga. Misalnya [0: "small", 1: "medium", 2: "large"]mungkin TIDAK akan menghasilkan["small", "medium", "large"]
Simon Bengtsson
55

Anda dapat memetakan kamus ke array nilai:

let colors = colorsForColorScheme.map { $0.1 }

Penutupan mengambil tuple nilai kunci dari kamus dan hanya mengembalikan nilai. Jadi, fungsi peta menghasilkan array nilai.

Versi yang lebih mudah dibaca dari kode yang sama:

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

MEMPERBARUI

Dari Xcode 9.0, nilai kamus dapat diakses menggunakan valuesproperti, yang sesuai dengan Collectionprotokol:

let colors = colorsForColorScheme.values

Biasanya Anda hanya menginginkannya sebagai array:

let colors = Array(dict.values)

dan hanya itu.

pjuzeliunas
sumber
2
Tapi sebenarnya ini adalah cara yang mudah dibaca untuk mendapatkan array let colors = Array (colorsForColorScheme.values)
Renetik
1
cinta solusi ini
Navy Seal
@pjuzeliunas karena ini adalah jawaban terbaik di sini, saya baru saja mengedit yang terbaru untuk tahun 2020. jelas-jelas santai, edit dll! bersorak dan terima kasih!
Fattie
10

Menggunakan colorsForColorScheme.map({$0.value})

Vishal kundaliya
sumber
8

Anda dapat membuat ekstensi aktif LazyMapCollection

public extension LazyMapCollection  {

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

colorsForColorSchemes.values.toArray() atau colorsForColorSchemes.keys.toArray()

GSerjo
sumber
3

Pertama, dari pernyataan berikut, tampaknya nama variabel (kamus) Anda colorsForColorScheme

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

saat Anda mencoba untuk mendapatkan nilai-nilai dari colorsForColorSchemeskamus ketika Anda melakukannya-

let colors: [UIColor] = colorsForColorSchemes.values

yang seharusnya memberi Anda kesalahan waktu kompilasi. Lagi pula saya berasumsi bahwa Anda memiliki kesalahan ketik, dan nama kamus Anda adalah colorsForColorSchemes. Jadi, inilah solusinya-

Seperti disebutkan sebelumnya, karena properti inference tipe di swift, kode Anda dapat menyimpulkan bahwa tipe yang dikembalikan dari .valuesfungsi mengembalikan array UIColor. Namun, Swift ingin menjadi tipe-aman, jadi ketika Anda menyimpan nilai-nilai dalam colorsarray, Anda perlu mendefinisikannya secara eksplisit. Untuk swift 5 ke atas, sekarang Anda bisa melakukan follow-

let colors = [UIColor](colorsForColorSchemes.values)
Natasha
sumber