2016-07-19 18 views
12

में शब्दकोश में मैं Person की वस्तुओं की एक सरणी है:मानचित्र सरणी स्विफ्ट

class Person { 
    let name:String 
    let position:Int 
} 

और सरणी है:

let myArray = [p1,p1,p3] 

मैं मैप करने के लिए myArray का एक शब्दकोश होना चाहता हूँ [position:name] क्लासिक समाधान है:

var myDictionary = [Int:String]() 

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

है किसी भी सुरुचिपूर्ण तरीका ख y स्विफ्ट tuples से ऐसा करने के लिए है कि कार्यात्मक दृष्टिकोण map, flatMap ... या अन्य आधुनिक स्विफ्ट शैली

+0

में काम नहीं करता आपका बढ़िया तरीका ज्यादा प्रदर्शन में बेहतर है – AamirR

उत्तर

28

ठीक map इस का एक अच्छा उदाहरण है, क्योंकि इसके सिर्फ पाशन के रूप में ही नहीं है, आप कर सकते हो se reduce इसके बजाय यह आपके वस्तु के प्रत्येक ले लिया गठबंधन और एकल मान में बदलने के लिए:

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

इस विधि मैं के बारे में सोच रहा था। – Fogmeister

+1

मुझे यह दृष्टिकोण पसंद है, लेकिन यह एक शब्दकोश लोड करने के लिए बस एक लूप बनाने से अधिक कुशल है? मुझे प्रदर्शन के बारे में चिंता है क्योंकि ऐसा लगता है कि यह हर आइटम के लिए एक बड़ी बड़ी शब्दकोश की एक नई म्यूटेबल प्रतिलिपि बनाना है ... –

+0

यह वास्तव में एक लूप है, इस तरह इसे लिखने के लिए सरल तरीका है, प्रदर्शन समान है या किसी भी तरह बेहतर है सामान्य लूप – Tj3n

4

आप Dictionary प्रकार के लिए कस्टम प्रारंभकर्ता लिख ​​सकते हैं, उदाहरण के लिए:

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

और उसके बाद के लिए map का उपयोग Person के अपने सरणी:

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

आप एक समारोह को कम कर सकते हैं।

let dictionary = myArray.reduce([Int: Person]()){ 
    (total, person) in 
    var totalMutable = total 
    totalMutable.updateValue(person, forKey: total.count) 
    return totalMutable 
} 
: सबसे पहले मैं व्यक्ति वर्ग

class Person { 
    var name:String 
    var position:Int 

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

बाद के लिए एक नामित प्रारंभकर्ता बना लिया है, मैं मान

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

और अंत में, शब्दकोश चर परिणाम है की किसी सरणी प्रारंभ किया है

15

Swift 4 में आप intoreduce के संस्करण का उपयोग करके @ Tj3n के दृष्टिकोण को अधिक स्वच्छ और कुशलता से कर सकते हैं यह अस्थायी dictio से छुटकारा पाता है नारी और वापसी मूल्य इसलिए यह पढ़ने के लिए तेज़ और आसान है।

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) 

नोट: स्विफ्ट 3.

संबंधित मुद्दे