以下是我难以理解的代码:
let rectToDisplay = self.treasures.reduce(MKMapRectNull) { //1
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in //2
let treasurePointRect = MKMapRect(origin: treasure.location.mapPoint, size: MKMapSize(width: 0, height: 0)) //3
return MKMapRectUnion(mapRect, treasurePointRect)
}
我对减少功能的理解是:
var people [] // an array of objects
var ageSum = 0
ageSum = people.reduce(0) { $0 + $1.age}
//(0) = initial value
//$0 = running total
//$1 = an object in an array
我对封闭的理解是:
{ (params) -> returnType in
statements
}
我对代码的理解是:
// 1 = reduce函数的初始值设置为(MKMapRectNull)
// 2 =使用两个返回MKMapRect
的参数传递一个闭包,而不是一个正在运行的总数和一个数组中的对象:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect
// 3 =这就是我被困的地方。使用两个参数MKMapRect
和origin: treasure.location.mapPoint
size: MKMapSize(width: 0, height: 0)
问题1 :如果传入的值为MKMapSize
,0,0
将如何计算?如何获取后续值并添加它们?
问题2:当此行返回//2 closure
return MKMapRectUnion(mapRect, treasurePointRect)
时,它是如何成为运行总计的,以及它如何知道到达下一个自我元素。宝藏?
答案 0 :(得分:7)
答案2:
对闭包的第二个(第三个,第四个)调用的第一个参数是前一个闭包调用的 result 输出。唯一的例外是第一次调用,它没有先前的继承调用,这就是为什么reduce将值0作为第二个参数 - 这是一个特殊值,可以输入第一个调用。
让我们假设以下场景 - 您有一组数字:
let a = [1,2,3]
并且您希望使用reduce:
找到总和let sum = reduce(a,0) { (accumulator, nextValue) in accumulator + nextValue }
让我们看看每次通话会发生什么:
call# acc next result
1 0 1 0+1 -> 1 # the zero is from reduce's second arg
2 1 2 1+2 -> 3 # the 1 is from the previous result
3 3 3 3+3 -> 6
现在我们已经耗尽了要处理的元素,所以我们返回最终值6,这实际上是1,2和3的总和
让我们想象一个稍微复杂的场景 - 在字符串中添加一系列格式化的数字值。这是减少:
let sum = reduce(a,"") { (accumulator, nextValue) in accumulator + nextValue }
它看起来几乎相同,但你会注意到 initial 设置为""
而不是0.运算符+现在组合了一个String和一个Int。
call# acc next result
1 "" 1 ""+1 -> "1"
2 "1" 2 "1"+2 -> "12"
3 "12" 3 "12"+3 -> "123"
我们已经完成了,可以输出字符串,或者其他什么。
现在让我们看看你的第一个问题!
向地图添加一系列点类似于(但不完全相同)将数字加在一起;它更接近字符串示例,其中累加器与数组元素(整数/宝藏位置)具有不同的类型(字符串/映射)。
您当然可以将“城堡灰色头骨”添加到空白地图中,然后将“阴暗海湾”添加到带有灰色头骨的地图上,然后将“宝藏位置”添加到带有“城堡灰色头骨”的地图中已经吸引了“阴暗的海湾”。然后你就完成了,你可以开始寻宝了。
您的初始值不是零,(或“”),而是空地图。
当添加新点(rect)时,它将被添加到具有上一点的 map ,它不会直接添加到上一点。
前一点留在地图上,没有变化!它附近只有一个新的地图标记,用来分享故事。
关于大小零矩形如何做任何事情的问题,我认为这与点相同。
答案 1 :(得分:3)
如果从命令性的角度思考cursor.executemany("INSERT INTO contacts VALUES (?,?)", list)
有帮助,那么这基本上就是您的代码所做的事情:
reduce