代码之家  ›  专栏  ›  技术社区  ›  Chris Marshall

从reduce获取任意类型

  •  0
  • Chris Marshall  · 技术社区  · 6 年前

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

    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
    }
    

    所以返回的rect包含蒸馏点。

    是的,我知道我可以简单地扩展数组(使用类型限定符)来使用计算属性来实现这一点,但是这样做会破坏这一目的。以上是相当有效的,我不想增加开销,只是为了花哨(这意味着,即使我可以做到,它也可能效率太低,无法使用)。

    这更多的是一种好奇心的探索,而不是技术需求。上面的代码对我来说很好,而且比较迅速。

    2 回复  |  直到 6 年前
        1
  •  2
  •   vadian    6 年前

    你是说

    // calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
    let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
    
        2
  •  1
  •   Dávid Pásztor    6 年前

    您可以创建一个 struct 用于保存最小/最大经度和纬度值,然后使用 reduce ,其中使用这些的初始值创建初始结果,然后创建 结构 有必要的 min / max 计算。

    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)