Swift:使用闭包减少函数

时间:2015-05-05 03:10:10

标签: swift mapkit reduce

以下是我难以理解的代码:

  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 =这就是我被困的地方。使用两个参数MKMapRectorigin: treasure.location.mapPoint

调用结构size: MKMapSize(width: 0, height: 0)

问题1 :如果传入的值为MKMapSize0,0将如何计算?如何获取后续值并添加它们?

问题2:当此行返回//2 closure return MKMapRectUnion(mapRect, treasurePointRect)时,它是如何成为运行总计的,以及它如何知道到达下一个自我元素。宝藏?

2 个答案:

答案 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