Mar*_*ina 135 dictionary swift
我想在字典中的所有键上映射一个函数.我希望像下面这样的东西可以工作,但过滤器不能直接应用于字典.实现这一目标的最简洁方法是什么?
在这个例子中,我试图将每个值递增1.但这对于示例来说是偶然的 - 主要目的是弄清楚如何将map()应用于字典.
var d = ["foo" : 1, "bar" : 2]
d.map() {
$0.1 += 1
}
Run Code Online (Sandbox Code Playgroud)
Bre*_*don 254
斯威夫特4
好消息!Swift 4包含一种mapValues(_:)方法,该方法使用相同的键但不同的值构造字典的副本.它还包括一个filter(_:)过载它返回一个Dictionary,以及init(uniqueKeysWithValues:)和init(_:uniquingKeysWith:)初始化来创建一个Dictionary从元组的任意序列.这意味着,如果您想要更改键和值,您可以这样说:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
还有用于将字典合并在一起的新API,用缺省元素替换缺省值,对值进行分组(将集合转换为数组字典,通过将集合映射到某个函数的结果来键入)等等.
在讨论引入这些功能的SE-0165提案时,我多次提出这个Stack Overflow的答案,我认为大量的upvotes有助于证明需求.谢谢你的帮助让Swift变得更好!
斯威夫特3
mapValues(_:)是一个扩展方法filter(_:)和Dictionary.它的定义如下:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
由于init(uniqueKeysWithValues:)符合init(_:uniquingKeysWith:),并且其Dictionary类型是(键,值)元组,这意味着您应该能够执行以下操作:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
但是,这实际上不会分配给mapValues(_:)-typed变量.该filter(_:)方法被定义为始终返回一个数组(the Dictionary),即使对于其他类型的字典也是如此.如果你编写一个构造函数,它将把一个二元组的数组转换为一个,init(uniqueKeysWithValues:)并且所有这些构造函数都适用于这个世界:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
您甚至可能希望编写特定于字典的版本,init(_:uniquingKeysWith:)以避免显式调用构造函数.在这里,我还包括了一个实现Dictionary:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
我使用了不同的名称,因为否则只有返回值会区分这两种方法,这会使代码非常模糊.
像这样使用它:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
顺便说一句,出于许多目的,您可能只想映射值:
let newDict = Dictionary(uniqueKeysWithValues:
oldDict.map { key, value in (key.uppercased(), value.lowercased()) })
Run Code Online (Sandbox Code Playgroud)
原因是mapValues(_:)如果两个最终映射到同一个键,可能会丢失对.filter(_:)另一方面,总是保留钥匙,所以这不是危险.
Ima*_*tit 41
使用Swift 4,您可以使用以下五个片段中的一个来解决您的问题.
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 works
print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]
Run Code Online (Sandbox Code Playgroud)
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 works
let newDictionary = Dictionary(uniqueKeysWithValues: tupleArray)
print(newDictionary) // prints: ["baz": 6, "foo": 2, "bar": 3]
Run Code Online (Sandbox Code Playgroud)
Dictionary reduce(_:_:)方法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]
Run Code Online (Sandbox Code Playgroud)
reduce(into:_:) Dictionary下标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]
Run Code Online (Sandbox Code Playgroud)
subscript(_:default:) Dictionary下标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]
Run Code Online (Sandbox Code Playgroud)
Air*_*ity 18
虽然这里的大多数答案都集中在如何映射整个字典(键和值),但问题实际上只是想映射值.这是一个重要的区别,因为映射值允许您保证相同数量的条目,而映射键和值可能会导致重复键.
这是一个扩展名,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)))
}
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*ark 11
最干净的方法是添加map到Dictionary:
extension Dictionary {
mutating func map(transform: (key:KeyType, value:ValueType) -> (newValue:ValueType)) {
for key in self.keys {
var newValue = transform(key: key, value: self[key]!)
self.updateValue(newValue, forKey: key)
}
}
}
Run Code Online (Sandbox Code Playgroud)
检查它是否有效:
var dic = ["a": 50, "b": 60, "c": 70]
dic.map { $0.1 + 1 }
println(dic)
dic.map { (key, value) in
if key == "a" {
return value
} else {
return value * 2
}
}
println(dic)
Run Code Online (Sandbox Code Playgroud)
输出:
[c: 71, a: 51, b: 61]
[c: 142, a: 51, b: 122]
Run Code Online (Sandbox Code Playgroud)
您也可以使用reduce而不是地图.能做reduce任何map可以做的事情!
let oldDict = ["old1": 1, "old2":2]
let newDict = reduce(oldDict, [String:Int]()) { dict, pair in
var d = dict
d["new\(pair.1)"] = pair.1
return d
}
println(newDict) // ["new1": 1, "new2": 2]
Run Code Online (Sandbox Code Playgroud)
将它包装在扩展中是相当容易的,但即使没有扩展,它也可以让你通过一个函数调用做你想做的事.
雨燕5
字典的map函数带有这种语法。
dictData.map(transform: ((key: String, value: String)) throws -> T)
你可以将闭包值设置为此
var dictData: [String: String] = [
"key_1": "test 1",
"key_2": "test 2",
"key_3": "test 3",
"key_4": "test 4",
"key_5": "test 5",
]
dictData.map { (key, value) in
// Operations on values or key
}
Run Code Online (Sandbox Code Playgroud)
可能会给出这个警告Result of call to 'map' is unused
然后只需_ =在变量之前设置即可。
也许它会对你有帮助
谢谢。
| 归档时间: |
|
| 查看次数: |
76637 次 |
| 最近记录: |