从 Reduce 获取任意类型

Getting An Arbitrary Type From Reduce

我正在做一个非常简单的操作。我正在对地图中的一堆位置进行排序以创建一个封闭的圆圈,如下所示:

var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180

for coord in inCoordinates {
    maxLong = max(coord.longitude, maxLong)
    maxLat = max(coord.latitude, maxLat)
    minLong = min(coord.longitude, minLong)
    minLat = min(coord.latitude, minLat)
}

let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0

return MKCircle(center: center, radius: radiusInMeters)

非常简单(是的,我知道 IDL 问题,但我想保持简单)。

我想知道的是,如果有某种方法可以将循环简化为 reduce 的变体,那么您最终会得到如下结果:

let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
    // Magic Happens Here -Queue Doug Henning GIF
}

所以返回的矩形包含蒸馏点。

是的,我知道我可以简单地扩展 Array(可能带有类型限定符)来使用计算的 属性 来执行此操作,但这有点违背了这样做的目的。以上是相当有效的,我宁愿不增加开销,只是为了花哨(这意味着,即使我能做到,使用起来也可能效率太低)。

与其说是技术需求,不如说这是一种好奇心探索。上面的代码对我来说很好,而且比较活泼。

你是说

// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { [=10=].union(MKMapRect(origin: MKMapPoint(), size: MKMapSize())) }

您可以创建一个 struct 来保存 min/max 经度和纬度值,然后使用 reduce,其中您使用这些的初始值来创建初始结果,然后使用必要的 min/max 计算创建 struct 的更新版本。

struct MinMaxCoordinates {
    let maxLong:Double
    let maxLat:Double
    let minLong:Double
    let minLat:Double
}


let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
    return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})

let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0

return MKCircle(center: center, radius: radiusInMeters)