为了账号安全,请及时绑定邮箱和手机立即绑定

将map()应用于Swift中的字典最简洁的方法是什么?

将map()应用于Swift中的字典最简洁的方法是什么?

慕尼黑5688855 2019-08-17 15:31:43
将map()应用于Swift中的字典最简洁的方法是什么?我想在字典中的所有键上映射一个函数。我希望像下面这样的东西可以工作,但过滤器不能直接应用于字典。实现这一目标的最简洁方法是什么?在这个例子中,我试图将每个值递增1.但这对于示例来说是偶然的 - 主要目的是弄清楚如何将map()应用于字典。var d = ["foo" : 1, "bar" : 2]d.map() {     $0.1 += 1}
查看完整描述

3 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

Swift 4+

好消息!Swift 4包含一种mapValues(_:)方法,该方法使用相同的键但不同的值构造字典的副本。它还包括一个filter(_:)过载它返回一个Dictionary,以及init(uniqueKeysWithValues:)init(_:uniquingKeysWith:)初始化来创建一个Dictionary从元组的任意序列。这意味着,如果您想要更改键和值,您可以这样说:

let newDict = Dictionary(uniqueKeysWithValues:
    oldDict.map { key, value in (key.uppercased(), value.lowercased()) })

还有用于将字典合并在一起的新API,用缺省元素替换缺省值,对值进行分组(将集合转换为数组字典,通过将集合映射到某个函数的结果来键入)等等。

在讨论引入这些功能的SE-0165提案时,我多次提出这个Stack Overflow的答案,我认为大量的upvotes有助于证明需求。谢谢你的帮助让Swift变得更好!


查看完整回答
反对 回复 2019-08-17
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

使用Swift 5,您可以使用以下五个代码段中的一个来解决您的问题。


#1。使用Dictionary mapValues(_:)方法

let dictionary = ["foo": 1, "bar": 2, "baz": 5]let newDictionary = dictionary.mapValues { value in
    return value + 1}//let newDictionary = dictionary.mapValues { $0 + 1 } // also worksprint(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]

#2。使用Dictionary map方法和init(uniqueKeysWithValues:)初始化程序

let dictionary = ["foo": 1, "bar": 2, "baz": 5]let tupleArray = dictionary.map { (key: String, value: Int) in
    return (key, value + 1)}//let tupleArray = dictionary.map { ($0, $1 + 1) } // also workslet newDictionary = Dictionary(uniqueKeysWithValues: tupleArray)print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]

#3。使用Dictionary reduce(_:_:)方法或reduce(into:_:)方法

let dictionary = ["foo": 1, "bar": 2, "baz": 5]let newDictionary = dictionary.reduce([:]) { (partialResult: [String: Int], tuple: (key: String, value: Int)) in
    var result = partialResult
    result[tuple.key] = tuple.value + 1
    return result}print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]
let dictionary = ["foo": 1, "bar": 2, "baz": 5]let newDictionary = dictionary.reduce(into: [:]) { (result: inout [String: Int], tuple: (key: String, value: Int)) in
    result[tuple.key] = tuple.value + 1}print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]

#4。使用Dictionary subscript(_:default:)下标

let dictionary = ["foo": 1, "bar": 2, "baz": 5]var newDictionary = [String: Int]()for (key, value) in dictionary {
    newDictionary[key, default: value] += 1}print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]

#5。使用Dictionary subscript(_:)下标

let dictionary = ["foo": 1, "bar": 2, "baz": 5]var newDictionary = [String: Int]()for (key, value) in dictionary {
    newDictionary[key] = value + 1}print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]


查看完整回答
反对 回复 2019-08-17
?
一只名叫tom的猫

TA贡献1906条经验 获得超2个赞

虽然这里的大多数答案都集中在如何映射整个字典(键值)上,但问题实际上只是想映射值。这是一个重要的区别,因为映射值允许您保证相同数量的条目,而映射键和值可能会导致重复键。

这是一个扩展名,mapValues允许您只映射值。请注意,它还init使用一系列键/值对来扩展字典,这比从数组初始化更通用:

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

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


查看完整回答
反对 回复 2019-08-17
  • 3 回答
  • 0 关注
  • 1124 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信