2016-07-19 10 views
12

yılında Sözlüğe [position:name] klasik bir çözümdür: Harita dizisi Ben <code>Person</code> 'ın nesneler dizisi var Swift

var myDictionary = [Int:String]() 

for person in myArray { 
    myDictionary[person.position] = person.name 
} 

herhangi zarif bir yolu b yoktur

extension Dictionary { 
    public init(keyValuePairs: [(Key, Value)]) { 
     self.init() 
     for pair in keyValuePairs { 
      self[pair.0] = pair.1 
     } 
    } 
} 

ve sonra için map kullanın: y Swift dizilerini örneğin, Sen Dictionary türü için özel başlatıcı yazabilirsiniz

+0

yılında Çalışmaz – AamirR

cevap

28

Tamam map u can, döngü olarak nedeniyle sadece aynı bunun iyi bir örnek değil

let myDictionary = myArray.reduce([Int: String]()) { (dict, person) -> [Int: String] in 
    var dict = dict 
    dict[person.position] = person.name 
    return dict 
} 

//[2: "b", 3: "c", 1: "a"] 
+0

Bu aklımdan yöntemidir. – Fogmeister

+1

Bu yaklaşımı beğendim, ancak bu bir sözlük yüklemek için bir döngü oluşturmaktan daha mı verimli? Performans hakkında endişeleniyorum çünkü her öğe için daha büyük bir sözlüğün yeni bir değişmez kopyasını oluşturmak zorunda gibi görünüyor ... –

+0

aslında bir döngü, bu şekilde yazmak için basitleştirilmiş bir yol, performans aynı veya bir şekilde daha iyi normal döngüden daha – Tj3n

4

fonksiyonel yaklaşımla map, flatMap ... ya diğer modern Swift tarzı ile bunu Person sizin dizisi:

var myDictionary = Dictionary(keyValuePairs: myArray.map{($0.position, $0.name)}) 
1

Bir azaltmak işlevini kullanabilirsiniz: se reduce bunun yerine, birleştirmek ve tek bir değere dönüşme Nesnenizin her sürdü.

let dictionary = myArray.reduce([Int: Person]()){ 
    (total, person) in 
    var totalMutable = total 
    totalMutable.updateValue(person, forKey: total.count) 
    return totalMutable 
} 
: Önce Kişi sınıfına

class Person { 
    var name:String 
    var position:Int 

    init(_ n: String,_ p: Int) { 
    name = n 
    position = p 
    } 
} 

Daha sonra için belirlenmiş bir başlatıcı oluşturduk, ben değerlerine

let myArray = [Person("Bill",1), 
       Person("Steve", 2), 
       Person("Woz", 3)] 

Ve nihayet, sözlük değişken sonucunu sahip bir dizi başlatıldı ettik

15

Swift 4reduce'un into versiyonunu kullanarak @ Tj3n'in yaklaşımını daha temiz ve verimli bir şekilde yapabilirsiniz. Geçici dictio'dan kurtulur. nary ve dönüş değeri, daha hızlı ve daha kolay okunur.

struct Person { 
    let name: String 
    let position: Int 
} 
let myArray = [Person(name:"h", position: 0), Person(name:"b", position:4), Person(name:"c", position:2)] 
let myDict = myArray.reduce(into: [Int: String]()) { 
    $0[$1.position] = $1.name 
} 
print(myDict) 

Not: klasik yolu performansında çok daha iyidir Swift 3.