2015-08-23 13 views
11

मैं मुसीबत map की स्विफ्ट 2 की विशेष शैली पता लगाना हो रही है वापस जाने के लिए:स्विफ्ट 2 में एक शब्दकोश नक्शे पर इस्तेमाल करते हुए एक शब्दकोश

मैं एक शब्दकोश में पढ़ रहा हूँ (एक plist फ़ाइल से), तो मैं मिल गया है एक [String: AnyObject]:

let dictionary = NSDictionary(contentsOfFile: path) as? [String: AnyObject] 

मेरा लक्ष्य लकड़हारा उदाहरणों में से एक शब्दकोश में Strings का एक शब्दकोश से बदलने के लिए है। यह [String: XCGLogger] होगा:

let loggers = dictionary 
    .map { (n, l) in [ n: newLogger(l.0, withLevel: level(l.1)) ] } 

बहरहाल, यह एक [[String: XCGLogger]] लौटा रहा है (जो शब्दकोशों की एक सरणी मेरे लिए तरह दिखता है)। सवाल यह है कि मैं एक फ्लैटेड डिक्शनरी कैसे वापस कर सकता हूं। जब मैं flatMap का उपयोग करने का प्रयास करता हूं तो मैं क्लोजर के बारे में त्रुटियों के आसपास मंडलियों में चलना शुरू करता हूं या (Key, Value) -> NSDictionary पर flatMap को कॉल करने में सक्षम नहीं हूं।

उत्तर

8

कारण यह है कि map केवल सरणी लौटा सकता है, न कि शब्दकोश। एक शब्दकोश आप कई रणनीतियों है प्राप्त करने के लिए, उदाहरण के लिए:

var loggers : [String: XCGLogger] = [:] 
dictionary.map{(n, l) in loggers[n] = newLogger(l.0, withLevel: level(l.1))} 

या शायद:

var loggers : [String: XCGLogger] = [:] 
for (n, l) in dictionary { 
    loggers[n] = newLogger(l.0, withLevel: level(l.1)) 
} 

वालों

+1

मेरे साथ समस्या यह है कि यह एक गैर-कार्यात्मक दृष्टिकोण है, और एक स्कैला प्रोग्रामर होने वाला पहला और सबसे महत्वपूर्ण, यह मुझे shivers देता है। क्या मानचित्र से 'डिक्शनरी' वापस करने का कोई तरीका नहीं है? मुझे अपने लक्ष्य को प्राप्त करने के लिए दुष्प्रभाव पर भरोसा करने के विचार से नफरत है ...! (मैं भी एक सरणी लौटने का विकल्प चुनता हूं और फिर उसे एक शब्दकोश में परिवर्तित कर सकता हूं ...) – Zac

+0

मैनुअल से: "मानचित्र एक ऐरे देता है जिसमें मैपिंग ट्रांसफॉर्मिंग के परिणाम होते हैं"। तो यह एक ऐरे देता है, और एक शब्दकोश वापस नहीं कर सकता है। मैं समझता हूं कि आप साइड इफेक्ट्स के बारे में डरते हैं, लेकिन इस बात पर विचार करें कि स्विफ्ट के पास 'var' और' let', 'struct' और 'classes'' के साथ, उन्हें सीमित करने का एक * बहुत अच्छा तरीका है और इसके अलावा, बुनियादी ढांचे के लिए आवश्यक है दुष्प्रभाव, मूल रूप से सी और उद्देश्य-सी में लिखा जा रहा है। इसलिए यदि आप स्विफ्ट और आईओएस में प्रोग्राम जारी रखना चाहते हैं, तो मुझे डर है कि आपको गैर-कार्यात्मक प्रोग्रामिंग तकनीकों के साथ परिचितता लेनी होगी। – Renzo

+0

समझा - हालांकि एक शर्म की बात है, मुझे उम्मीद थी कि स्विफ्ट 2 "अधिक कार्यात्मक" होगा। अच्छा कदम हालांकि ... निश्चित रूप से प्रत्येक पुनरावृत्ति के साथ करीब और करीब हो रहा है। मुझे उम्मीद नहीं है कि स्विफ्ट पूरी तरह से कार्यात्मक हो, लेकिन मुझे ये सुविधाएं विकसित करना पसंद है। – Zac

5
extension SequenceType { 
    func toDict<K : Hashable, V> 
    (@noescape convert: Generator.Element -> (K, V)) -> [K:V] { 
    var result: [K:V] = [:] 
    for x in self { 
     let (key, val) = convert(x) 
     result[key] = val 
    } 
    return result 
    } 
} 

dictionary.toDict { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) } 

या

extension Dictionary { 
    public init< 
    S : SequenceType where 
    S.Generator.Element == (Key, Value) 
    >(_ seq: S) { 
    self.init() 
    for (k, v) in seq { self[k] = v } 
    } 
} 

extension SequenceType { 
    func toDict<K : Hashable, V> 
    (@noescape convert: Generator.Element -> (K, V)) -> [K:V] { 
    return Dictionary(lazy(self).map(convert)) 
    } 
} 

dictionary.toDict { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) } 

या

extension Dictionary { 
    func map<K : Hashable, V>(@noescape transform: (Key, Value) -> (K, V)) -> [K:V] { 
    var result: [K:V] = [:] 
    for x in self { 
     let (key, val) = transform(x) 
     result[key] = val 
    } 
    return result 
    } 
} 

dictionary 
    .map { (n, l) in (n, newLogger(l.0, withLevel: level(l.1))) } 
1

@ रेंज़ो के जवाब से थोड़ा अधिक संक्षिप्त तरीके से उपयोग करेंगे को कम:

let loggers: [String: XCGLogger] = dictionary.reduce([:]){(var loggers, kv) in 
loggers[kv.0] = newLogger(kv.1.0, withLevel: level(kv.1.1)) 
return loggers 
} 

यह अधिक सुविधाजनक और स्पष्ट करता है, तो स्विफ्ट (कुंजी, मूल्य) में केवी संहार कर सकता है किया जाएगा। उम्मीद है कि स्विफ्ट का भविष्य संस्करण, हम ऐसा करने में सक्षम होंगे।

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