2015-04-05 12 views
3

我有一本字典,我想轉換每個項目的值,但保留原始字典的機智。這就是我要做的:如何使用地圖在Swift中轉換字典?

var someDict = [ 
    "a": 1, 
    "b": 2, 
    "c": 3 
] 

func convert(value: Int) -> [String: Int] { 
    return someDict.map({ 
     item in ???? 
    } 
} 

然後我試圖與該結束了:

convert(10) // Result: ["a":10, "b":20, "c":30] 
convert(20) // Result: ["a":20, "b":40, "c":60] 
convert(5) // Result: ["a":5, "b":10, "c":15] 
someDict // Result: ["a":1, "b":2, "c":3] 

我不是從documentation的語法明確本或者map是正確的做法。任何幫助或建議將不勝感激!

+0

看看http://stackoverflow.com/questions/24116271/whats-the-cleanest-way-of-applying-map-to-a-dictionary-in-swift – 2015-04-05 18:37:09

+0

不完全重複 - 這個問題是「我如何映射鍵」,而這是「如何映射值」。這些問題之間有相當大的差異,因爲映射鍵意味着改變條目的數量,而映射值不會......而且,這些值不必是可散列的。 – 2015-04-05 18:50:14

+0

@AirspeedVelocity:如果我正確理解引用的問題,它是關於更改字典中每個鍵的值(具體來說:將每個鍵的值遞增1),因此與此問題非常相似。此外,接受的答案顯示瞭如何映射鍵和值(對於我來說,看起來與您的答案類似):map()應用於字典,以及從一組鍵/值對創建的新字典)。 - 如果我錯了,糾正我,我會重新打開答案! – 2015-04-05 18:54:48

回答

6

有沒有直接的方法來映射字典中的值來創建一個新的字典。

您可以將字典本身傳遞到map,因爲它符合SequenceType。在字典中的情況下,它們的元件是一個鍵/值對:

// double all the values, leaving key unchanged 
map(someDict) { (k,v) in (k, v*2) } 

但是,這將導致對一個陣列,而不是一個新的字典。但如果你擴展Dictionary有一個初始化這需要鍵/值對的序列,然後你可以用它來創建一個新的字典:

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

let mappedDict = Dictionary(map(someDict) { (k,v) in (k, v*2) }) 
// mappedDict will be [「a」:2, 「b」:4, 「c」:6] 

這樣做的另一個缺點是,如果你改變了密鑰,您不能保證字典不會丟棄某些值(因爲它們的鍵可能映射到彼此的副本)。

但是,如果您只使用值,則可以以類似的方式僅對字典的值定義map的版本,並且保證保持相同數量的條目(因爲鍵不更改):

extension Dictionary { 
    func mapValues<T>(transform: Value->T) -> Dictionary<Key,T> { 
     return Dictionary<Key,T>(zip(self.keys, self.values.map(transform))) 
    } 
} 

let mappedDict = someDict.mapValues { $0 * 2 } 

從理論上講,這意味着您可以進行就地轉換。但是,這通常不是一種好的做法,最好將其留作創建一個新的字典,您可以隨時將其分配給舊的變量(請注意,陣列上沒有版本map進行就地更改,不像sort/sorted)。

+0

'extension'選項給了我'返回字典(zip(self.keys,self.values.map(transform))'帶有Swift 2.2的錯誤「參數標籤'(_ :)'與任何可用的重載不匹配' )'。我改變了這個循環來覆蓋'zip()'的返回值,並將每個值分配給每個鍵,一次一個:[Gist](https://gist.github。com/donut/2ba63046c6a1daecf8ea) – donut 2016-03-09 19:34:36

+0

@ donut你有什麼代碼片段嗎? – Hlung 2017-05-29 08:06:52

+0

沒關係,我做到了https://gist.github.com/hlung/243974186c7f67ab3063fde5cf9d8c12 – Hlung 2017-05-29 08:34:32

相關問題