Swift, Diziye Ayarlandı


187

Bir NSSetdönüştürülebilir Arraykullanarak set.allObjects()ancak yeni böyle bir yöntem yoktur Set(Swift 1.2 ile dahil edilmiş). Yine de Swift Set'i NSSet'e dönüştürerek ve allObjects()yöntemi kullanarak yapılabilir, ancak bu optimal değildir.

Yanıtlar:


352

Belirli bir Swift tüm unsurları ile bir dizi oluşturabilir Setbasitçe ile

let array = Array(someSet)

Bu çalışır, çünkü protokole Setuygun SequenceTypeve Arraybir dizi ile başlatılabilir. Misal:

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

4
Bir yan not olarak, let array = Array(someSet)Swift 2
Suragch

... veya myArray = myNSSet.allObjects olarak! [mySpecificType]
angelos.p

3
@plusangel: Evet, NSSetverilirse. Soru bir Swift hakkındaydı Set.
Martin R

@KendallHelmstetterGelner: Yukarıdaki kod örneğini hem Swift 2.3 hem de Swift 3 ile iki kez kontrol ettim. Benim için beklendiği gibi derlendi ve çalıştı. Hangi hatayı alıyorsun?
Martin R

@MartinR İlginç, NSManagedObject ilişkisinden bir kümeyle deniyordum ve o zaman Array yapıcısını beğenmedim - şimdi sorunu yeniden oluşturmaya çalışıyorum, yapamam. Array yapıcısına olsa "arrayLiteral:" etiketi eklemek zorunda. Bu yüzden kimseyi şaşırtmaz önceki yorumum kaldırıldı, kontrol için teşekkürler! Swift kılavuzunun neden bu dönüşüm formuna sahip olduğunu bilmiyorum ...
Kendall Helmstetter Gelner

21

En basit durumda , Swift 3 ile kullanabileceğiniz Array'ın init(_:)bir olsun başlatıcı Arraybir mesafede Set. init(_:)aşağıdaki beyanı içerir:

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

Bir dizinin öğelerini içeren bir dizi oluşturur.

Kullanımı:

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

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

Ancak , aynı zamanda her bir unsuru üzerinde bazı işlemleri gerçekleştirmek istiyorsanız senin Setbir dönüştürülmesi sırasında Arraykullanabileceğiniz map, flatMap, sort, filterve sağladığı diğer işlevsel yöntemler 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]

Bu yöntemlerden birini kullanarak isteğe bağlı dizi isteğe bağlı dizi yapabilirsiniz.
tzaloga

11

İLAVE :

Swift'in Set ve Dictionary için TANIMLI SİPARİŞİ yoktur.Bu nedenle diziniz gibi beklenmedik sonuçların alınmasını önlemek için sort () yöntemini kullanmalısınız ["a", "b"] veya ["b", "a "] ve bunu istemezsiniz.

DÜZELTME İÇİN:

SETLER İÇİN

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

Sonuç: ["a", "b", "c"]

Sıralanmamış ()

Olabilir:

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

basit matematik: 3! = 6


10

Sana sıralanmamış veren basit uzantısı oluşturulan Arraybir özelliği olarak Setyer Swift 4.0 .

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

Sıralı bir dizi istiyorsanız, ek bir hesaplanmış özellik ekleyebilir veya mevcut diziyi ihtiyaçlarınıza uyacak şekilde değiştirebilirsiniz.

Bunu kullanmak için

let array = set.array

3

Swift 2.x ve üstü için geçerli cevap (Koleksiyon Türleri hakkında Swift Programlama Dili kılavuzundan) ya Set girişleri üzerinde yineleme yapmak gibi görünüyor:

for item in myItemSet {
   ...
}

Veya "sıralanmış" yöntemini kullanmak için:

let itemsArray = myItemSet.sorted()

Swift tasarımcıları allObjects'i bir erişim mekanizması olarak beğenmedi gibi görünüyor çünkü Setler gerçekten sipariş edilmedi, bu yüzden açık bir sipariş uygulanmadan bir diziden çıkmadığınızdan emin olmak istediler.

Sıralama yükü istemiyorsanız ve sipariş umurumda değil, ben genellikle bir dizi ayıklamak için biraz daha hızlı olması gereken map veya flatMap yöntemlerini kullanın:

let itemsArray = myItemSet.map { $0 }

Belirli bir türde bir dizi olması gerekiyorsa (örneğin, yazılan bir küme olarak bildirilmeyen bir dizi yönetilen nesne ilişkisinden alınan haklar), aşağıdakileri içeren bir dizi oluşturabilirsiniz:

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

myItemSet.sorted()elemanların olmasını gerektirir Comparable. - her ikisinin de kümenin tüm öğelerini numaralandırarak bir dizi oluşturmasıyla myItemSet.map { $0 }aynı sonucu üretmelidir Array(myItemSet). İkincisi hala benim için çalışıyor, yukarıdaki yorumunuzla ilgili bazı ayrıntılar takdir edilecektir.
Martin R

-2

bu yöntemi çağır ve setini geç

func getArrayFromSet(set:NSSet)-> NSArray {

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

Bunun gibi :

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

2
Use Array (<Set>) daha iyi bir seçimdir
Sébastien REMY
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.