2015-08-23 25 views
11

Tôi đang gặp khó khăn để tìm ra phong cách đặc biệt Swift 2 của map:Sử dụng bản đồ trên một từ điển trong Swift 2, để trả về một từ điển

Tôi đọc trong một cuốn từ điển (từ một tập tin plist), vì vậy tôi 've có một [String: AnyObject]:

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

mục tiêu của tôi là để chuyển đổi từ một cuốn từ điển của Strings thành một cuốn từ điển các trường hợp logger. Đây sẽ là [String: XCGLogger]:

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

Tuy nhiên, điều này được trả lại một [[String: XCGLogger]] (trông giống như một loạt các từ điển đối với tôi). Câu hỏi đặt ra là làm thế nào để tôi trả lại một từ điển phẳng. Khi tôi cố gắng sử dụng flatMap Tôi bắt đầu chạy trong vòng kết nối xung quanh các lỗi về đóng cửa hoặc không thể gọi flatMap trên một loại (Key, Value) -> NSDictionary.

Trả lời

8

Lý do là map chỉ có thể trả về mảng và không phải từ điển. Để có được một cuốn từ điển bạn có một vài chiến lược, ví dụ:

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

hoặc có lẽ:

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

logger

+1

Vấn đề tôi có với điều này là nó là một cách tiếp cận phi chức năng, và là một lập trình viên Scala đầu tiên và quan trọng nhất, nó cho tôi rùng mình. Không có cách nào để trả lại một 'Từ điển' từ bản đồ? Tôi ghét ý tưởng dựa vào một tác dụng phụ để đạt được mục tiêu của mình ...! (Tôi thậm chí còn muốn trả lại một mảng và sau đó chuyển đổi nó thành một từ điển ...) – Zac

+0

Từ hướng dẫn sử dụng: "Bản đồ trả về một mảng chứa các kết quả chuyển đổi ánh xạ trên bản thân". Vì vậy, nó trả về một mảng, và không thể trả về một từ điển. Tôi hiểu bạn lo ngại về tác dụng phụ, nhưng hãy xem xét Swift có một cách * rất tốt để hạn chế chúng, với 'var' và' let', 'struct' và' classes' và hơn nữa, các khung công tác cơ bản yêu cầu tác dụng phụ, được viết ban đầu trong C và Objective-C. Vì vậy, nếu bạn muốn tiếp tục chương trình trong Swift và iOS, tôi sợ bạn phải làm quen với các kỹ thuật lập trình phi chức năng. – Renzo

+0

Hiểu - một sự xấu hổ mặc dù, tôi đã hy vọng Swift 2 sẽ "có nhiều chức năng hơn". Mặc dù có những bước tiến tốt ... chắc chắn sẽ tiến gần hơn và gần hơn với mỗi lần lặp lại. Tôi không mong đợi Swift sẽ hoàn toàn có chức năng, nhưng tôi thích thấy những tính năng này phát triển. – 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))) } 

Hoặc

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))) } 

Hoặc

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

cách Hơi ngắn gọn hơn từ @ câu trả lời Renzo của sẽ được sử dụng giảm:

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

Sẽ thuận tiện hơn và rõ ràng hơn nếu Swift có thể hủy kv vào (key, value). Hy vọng rằng phiên bản tương lai của Swift, chúng tôi sẽ có thể làm điều này.

Các vấn đề liên quan