闭包在方法 mapValues 中是如何工作的?
How does the closure work in the method mapValues?
我正在尝试了解 mapValues method works in the following code from Calendar Heatmap。
- 首先,函数加载字典:
private func readHeatmap() -> [String: Int]? {
guard let url = Bundle.main.url(forResource: "heatmap", withExtension: "plist") else { return nil }
return NSDictionary(contentsOf: url) as? [String: Int]
}
heatmap.plist 是一个 key/value 列表,如下所示:
<key>2019.5.3</key>
<integer>3</integer>
<key>2019.5.5</key>
<integer>4</integer>
<key>2019.5.7</key>
<integer>3</integer>
- 一个属性使用上面的函数初始化:
lazy var data: [String: UIColor] = {
guard let data = readHeatmap() else { return [:] }
return data.mapValues { (colorIndex) -> UIColor in
switch colorIndex {
case 0:
return UIColor(named: "color1")!
case 1:
return UIColor(named: "color2")!
case 2:
return UIColor(named: "color3")!
case 3:
return UIColor(named: "color4")!
default:
return UIColor(named: "color5")!
}
}
}()
- 最后将上面定义的
data
属性用在下面的函数中:
func colorFor(dateComponents: DateComponents) -> UIColor {
guard let year = dateComponents.year,
let month = dateComponents.month,
let day = dateComponents.day else { return .clear}
let dateString = "\(year).\(month).\(day)"
return data[dateString] ?? UIColor(named: "color6")!
}
Apple 的文档指出 mapValues
returns 字典“包含该字典的键以及由给定闭包转换的值。”
我的问题是,在 data.mapValues { (colorIndex) -> UIColor in
中传入闭包的值 colorIndex
到底是什么?是来自 heatmap.plist
吗?我很困惑如何将 String
从 colorFor(dateComponents: )
函数传递到 date
、date[dateString],但 colorIndex
是 Int。
本来data
是这样的:
"2019.5.3" : 3
"2019.5.5" : 4
"2019.5.7" : 3
假设你做了 data.mapValues(f)
,其中 f
是一个函数,生成的字典将如下所示:
"2019.5.3" : f(3)
"2019.5.5" : f(4)
"2019.5.7" : f(3)
所以现在,字典的值类型变为f
的return类型,而键类型保持不变。
what exactly is the value colorIndex
passed into the closure?
它是 data
中的每个值。每个值都会被传递到闭包中一次。
为了更清楚地看到这一点,我写了一种可以实现 mapValues
的可能方式:
extension Dictionary {
func myMapValues<T>(_ transform: (Value) throws -> T) rethrows -> [Key: T] {
var retVal = [Key: T]()
for entry in self {
retVal[entry.key] = try transform(entry.value)
}
return retVal
}
}
Is it from heatmap.plist?
间接地,是的。局部变量data
(即[String: Int]
)的内容原本来自heatmap.plist
,但mapValues
直接对已经从文件中读取的data
进行操作。
I'm confused how a String is passed into data
, data[dateString]
from the colorFor(dateComponents: )
function, but colorIndex
is Int
.
colorIndex
在这里无关紧要。 colorIndex
只是您传递给 mapValues
的函数的函数参数的名称。 mapValues
此时已被调用,字典的值已被转换。
您可以将 String
传递给 data
,因为 data
字典将 String
作为键。回想一下 mapValues
不会更改密钥类型。注意这个data
和局部变量data
是不一样的。我说的是类型 [String: UIColor]
.
的 lazy
属性 data
我正在尝试了解 mapValues method works in the following code from Calendar Heatmap。
- 首先,函数加载字典:
private func readHeatmap() -> [String: Int]? {
guard let url = Bundle.main.url(forResource: "heatmap", withExtension: "plist") else { return nil }
return NSDictionary(contentsOf: url) as? [String: Int]
}
heatmap.plist 是一个 key/value 列表,如下所示:
<key>2019.5.3</key>
<integer>3</integer>
<key>2019.5.5</key>
<integer>4</integer>
<key>2019.5.7</key>
<integer>3</integer>
- 一个属性使用上面的函数初始化:
lazy var data: [String: UIColor] = {
guard let data = readHeatmap() else { return [:] }
return data.mapValues { (colorIndex) -> UIColor in
switch colorIndex {
case 0:
return UIColor(named: "color1")!
case 1:
return UIColor(named: "color2")!
case 2:
return UIColor(named: "color3")!
case 3:
return UIColor(named: "color4")!
default:
return UIColor(named: "color5")!
}
}
}()
- 最后将上面定义的
data
属性用在下面的函数中:
func colorFor(dateComponents: DateComponents) -> UIColor {
guard let year = dateComponents.year,
let month = dateComponents.month,
let day = dateComponents.day else { return .clear}
let dateString = "\(year).\(month).\(day)"
return data[dateString] ?? UIColor(named: "color6")!
}
Apple 的文档指出 mapValues
returns 字典“包含该字典的键以及由给定闭包转换的值。”
我的问题是,在 data.mapValues { (colorIndex) -> UIColor in
中传入闭包的值 colorIndex
到底是什么?是来自 heatmap.plist
吗?我很困惑如何将 String
从 colorFor(dateComponents: )
函数传递到 date
、date[dateString],但 colorIndex
是 Int。
本来data
是这样的:
"2019.5.3" : 3
"2019.5.5" : 4
"2019.5.7" : 3
假设你做了 data.mapValues(f)
,其中 f
是一个函数,生成的字典将如下所示:
"2019.5.3" : f(3)
"2019.5.5" : f(4)
"2019.5.7" : f(3)
所以现在,字典的值类型变为f
的return类型,而键类型保持不变。
what exactly is the value
colorIndex
passed into the closure?
它是 data
中的每个值。每个值都会被传递到闭包中一次。
为了更清楚地看到这一点,我写了一种可以实现 mapValues
的可能方式:
extension Dictionary {
func myMapValues<T>(_ transform: (Value) throws -> T) rethrows -> [Key: T] {
var retVal = [Key: T]()
for entry in self {
retVal[entry.key] = try transform(entry.value)
}
return retVal
}
}
Is it from heatmap.plist?
间接地,是的。局部变量data
(即[String: Int]
)的内容原本来自heatmap.plist
,但mapValues
直接对已经从文件中读取的data
进行操作。
I'm confused how a String is passed into
data
,data[dateString]
from thecolorFor(dateComponents: )
function, butcolorIndex
isInt
.
colorIndex
在这里无关紧要。 colorIndex
只是您传递给 mapValues
的函数的函数参数的名称。 mapValues
此时已被调用,字典的值已被转换。
您可以将 String
传递给 data
,因为 data
字典将 String
作为键。回想一下 mapValues
不会更改密钥类型。注意这个data
和局部变量data
是不一样的。我说的是类型 [String: UIColor]
.
lazy
属性 data