2015-04-05 9 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

相关问题