Swift Atur ke Array

187

Sebuah NSSetdapat dikonversi menjadi Arraymenggunakan set.allObjects()tetapi tidak ada metode seperti itu di baru Set(diperkenalkan dengan Swift 1.2). Itu masih bisa dilakukan dengan mengonversi Swift Set ke NSSet dan menggunakanallObjects() metode ini tetapi itu tidak optimal.

Nasi goreng
sumber

Jawaban:

352

Anda dapat membuat array dengan semua elemen dari Swift yang diberikan Sethanya dengan

let array = Array(someSet)

Ini berfungsi karena Setsesuai dengan SequenceTypeprotokol dan Arraydapat diinisialisasi dengan urutan. Contoh:

let mySet = Set(["a", "b", "a"])  // Set<String>
let myArray = Array(mySet)        // Array<String>
print(myArray) // [b, a]
Martin R
sumber
4
Sebagai catatan tambahan, let array = Array(someSet)juga bekerja di Swift 2
Suragch
... atau biarkan myArray = myNSSet.allObjects as! [mySpecificType]
angelos.p
3
@plusangel: Ya, jika NSSetdiberikan. Pertanyaannya adalah tentang Swift Set.
Martin R
@KendallHelmstetterGelner: Saya telah memeriksa ulang contoh kode di atas dengan Swift 2.3 dan Swift 3. Ini dikompilasi dan berfungsi seperti yang diharapkan untuk saya. Kesalahan apa yang Anda dapatkan?
Martin R
@MartinR Menarik, saya mencobanya dengan satu set dari hubungan NSManagedObject, dan tidak suka konstruktor Array pada saat itu - sekarang saya mencoba mereproduksi masalahnya, saya tidak bisa. Saya harus menambahkan label "arrayLiteral:" ke konstruktor Array. Saya menghapus komentar saya sebelumnya sehingga tidak membingungkan siapa pun, terima kasih telah memeriksa! Saya tidak tahu mengapa panduan Swift tidak memiliki bentuk konversi ini ...
Kendall Helmstetter Gelner
21

Dalam kasus yang paling sederhana , dengan Swift 3, Anda dapat menggunakan Array's init(_:)initializer untuk mendapatkan Arraydari Set. init(_:)memiliki deklarasi berikut:

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

Membuat array yang mengandung elemen-elemen dari suatu urutan.

Pemakaian:

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

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

Namun , jika Anda juga ingin melakukan beberapa operasi pada setiap elemen dari Anda Setsementara mengubahnya menjadi sebuah Array, Anda dapat menggunakan map, flatMap, sort, filterdan metode fungsional lain yang disediakan oleh Collectionprotokol:

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
sumber
Menggunakan salah satu metode ini saya bisa membuat array opsional dari set opsional.
tzaloga
11

TAMBAHAN:

Swift tidak memiliki DEFINED ORDER untuk Set dan Kamus. Untuk alasan itu Anda harus menggunakan metode sortir () untuk mencegah dari mendapatkan hasil yang tidak terduga seperti array Anda dapat seperti ["a", "b"] atau ["b", "a "] dan kamu tidak menginginkan ini.

UNTUK MEMPERBAIKI INI:

UNTUK SET

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

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

Tanpa diurutkan ()

Itu bisa:

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

matematika sederhana: 3! = 6


sumber
10

Saya membuat ekstensi sederhana yang memberi Anda unsorted Arraysebagai properti Setdi Swift 4.0 .

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

Jika Anda menginginkan array yang diurutkan, Anda bisa menambahkan properti yang dihitung tambahan, atau memodifikasi yang sudah ada sesuai dengan kebutuhan Anda.

Untuk menggunakan ini, telepon saja

let array = set.array
CodeBender
sumber
3

Jawaban saat ini untuk Swift 2.x dan lebih tinggi (dari panduan Bahasa Pemrograman Swift pada Jenis Koleksi) tampaknya beralih ke entri Set seperti:

for item in myItemSet {
   ...
}

Atau, untuk menggunakan metode "diurutkan":

let itemsArray = myItemSet.sorted()

Tampaknya perancang Swift tidak menyukai allObjects sebagai mekanisme akses karena Set tidak benar-benar dipesan, jadi mereka ingin memastikan Anda tidak keluar dari array tanpa penerapan pemesanan eksplisit.

Jika Anda tidak ingin overhead penyortiran dan tidak peduli dengan pesanan, saya biasanya menggunakan metode peta atau flatMap yang seharusnya sedikit lebih cepat untuk mengekstrak array:

let itemsArray = myItemSet.map { $0 }

Yang akan membangun larik tipe yang disimpan Set, jika Anda memerlukannya menjadi larik tipe tertentu (katakanlah, hak dari kumpulan relasi objek terkelola yang tidak dideklarasikan sebagai set yang diketik) Anda dapat melakukan sesuatu seperti:

var itemsArray : [MyObjectType] = []
if let typedSet = myItemSet as? Set<MyObjectType> {
 itemsArray = typedSet.map { $0 }
}
Kendall Helmstetter Gelner
sumber
myItemSet.sorted()mensyaratkan bahwa unsur-unsurnya Comparable. - myItemSet.map { $0 }Harus menghasilkan hasil yang sama seperti Array(myItemSet), keduanya membuat array dengan menghitung semua elemen set. Yang terakhir masih bekerja untuk saya, beberapa detail pada komentar Anda di atas akan dihargai.
Martin R
-2

panggil metode ini dan lulus set Anda

func getArrayFromSet(set:NSSet)-> NSArray {

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

Seperti ini :

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
print(self.getArrayFromSet(letters))
Shubham bairagi
sumber
2
Use Array (<Set>) adalah pilihan yang lebih baik
Sébastien REMY