Swift: Reduce Function with a closure
Swift: Reduce Function with a closure
下面是我难以理解的代码:
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)
}
我对reduce函数的理解是:
var people [] // an array of objects
var ageSum = 0
ageSum = people.reduce(0) { [=12=] + .age}
//(0) = initial value
//[=12=] = running total
// = an object in an array
我对闭包的理解是:
{ (params) -> returnType in
statements
}
我对上面代码的理解是:
//1 = reduce 函数的初始值设置为 (MKMapRectNull)
//2 = 不是 运行 总和数组中的对象,而是传入一个带有两个参数的闭包 returns a MKMapRect
:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect
//3 = 这就是我卡住的地方。使用两个参数 origin: treasure.location.mapPoint
和 size: MKMapSize(width: 0, height: 0)
调用结构 MKMapRect
问题一:如果传入的值为0,0
,MKMapSize
如何计算?它是如何获取后续值并添加它们的?
问题2:当这一行返回到//2 closure
时return MKMapRectUnion(mapRect, treasurePointRect)
它是如何变成运行总数的,它是如何知道的到达 self.treasures 的下一个元素 ?
答案 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
现在我们有 运行 个元素要处理,所以我们 return 最终值 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"
我们完成了,可以打印出字符串,或其他任何东西。
现在来看你的第一个问题!
将一系列点添加到地图类似于(但不完全相同)将数字相加;它更接近字符串示例,其中累加器具有与数组元素(integer/treasure 位置)不同的类型(string/map)。
您当然可以将 "castle grey skull' to an empty map, and then add "shady cove" 添加到上面有灰色骷髅头的地图,然后将 'treasure location' 添加到已经有 "castle grey skull" 和 "shady cove" 的地图画上去,大功告成,可以开始寻宝了。
您的初始值不是零(或“”),而是空映射。
添加新点(矩形)时,它被添加到具有前一个点的地图,而不是直接添加到前一个点。
之前的点留在地图上,没有变化!它只是在附近有一个新的地图标记,可以与之分享故事。
关于你的问题,即大小为零的矩形如何做任何事情,我认为这与点相同。
如果从命令式的角度考虑 reduce
有帮助,那么这实际上就是您的代码正在做的事情:
var rectToDisplay = MKMapRectNull
for treasure in self.treasures {
let treasurePointRect = MKMapRect(origin: treasure.location.mapPoint, size: MKMapSize(width: 0, height: 0))
rectToDisplay = MKMapRectUnion(rectToDisplay, treasurePointRect)
}
下面是我难以理解的代码:
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)
}
我对reduce函数的理解是:
var people [] // an array of objects
var ageSum = 0
ageSum = people.reduce(0) { [=12=] + .age}
//(0) = initial value
//[=12=] = running total
// = an object in an array
我对闭包的理解是:
{ (params) -> returnType in
statements
}
我对上面代码的理解是:
//1 = reduce 函数的初始值设置为 (MKMapRectNull)
//2 = 不是 运行 总和数组中的对象,而是传入一个带有两个参数的闭包 returns a MKMapRect
:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect
//3 = 这就是我卡住的地方。使用两个参数 origin: treasure.location.mapPoint
和 size: MKMapSize(width: 0, height: 0)
MKMapRect
问题一:如果传入的值为0,0
,MKMapSize
如何计算?它是如何获取后续值并添加它们的?
问题2:当这一行返回到//2 closure
时return MKMapRectUnion(mapRect, treasurePointRect)
它是如何变成运行总数的,它是如何知道的到达 self.treasures 的下一个元素 ?
答案 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
现在我们有 运行 个元素要处理,所以我们 return 最终值 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"
我们完成了,可以打印出字符串,或其他任何东西。
现在来看你的第一个问题!
将一系列点添加到地图类似于(但不完全相同)将数字相加;它更接近字符串示例,其中累加器具有与数组元素(integer/treasure 位置)不同的类型(string/map)。
您当然可以将 "castle grey skull' to an empty map, and then add "shady cove" 添加到上面有灰色骷髅头的地图,然后将 'treasure location' 添加到已经有 "castle grey skull" 和 "shady cove" 的地图画上去,大功告成,可以开始寻宝了。
您的初始值不是零(或“”),而是空映射。
添加新点(矩形)时,它被添加到具有前一个点的地图,而不是直接添加到前一个点。
之前的点留在地图上,没有变化!它只是在附近有一个新的地图标记,可以与之分享故事。
关于你的问题,即大小为零的矩形如何做任何事情,我认为这与点相同。
如果从命令式的角度考虑 reduce
有帮助,那么这实际上就是您的代码正在做的事情:
var rectToDisplay = MKMapRectNull
for treasure in self.treasures {
let treasurePointRect = MKMapRect(origin: treasure.location.mapPoint, size: MKMapSize(width: 0, height: 0))
rectToDisplay = MKMapRectUnion(rectToDisplay, treasurePointRect)
}