微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 swift 中简化此 foreach 循环以在嵌套数组中查找最小值/最大值

如何解决在 swift 中简化此 foreach 循环以在嵌套数组中查找最小值/最大值

我很想摆脱 foreach 循环。目前我正在做一个 foreach 循环来填充一个临时变量来分隔我的数组以获得每个纬度/经度的最小值/最大值。

例如:slopeLatLonArray = [ [111,111],[111.1,111.2] ]

 func drawFullRouteOverlay() {
    /// Reset Array to Nil
    vLocations = []

    /// populate vLocations as a CLLocation2D
    for index in slopeLatLonArray.indices {
      vLocations.append(CLLocationCoordinate2D(latitude: Double(slopeLatLonArray[index][0]),longitude: Double(slopeLatLonArray[index][1])))
    }
    
    /// Draw the resulting polyline
    let polyline = MKpolyline(coordinates: vLocations,count: vLocations.count)
    vcTrainMapView.addOverlay(polyline)
    
    /// Bunch of stuffs to do to get the Max/Min of Lat/Lon
    var tempLat: [Double] = []
    var tempLon: [Double] = []
    
    slopeLatLonArray.forEach {
      tempLat.append($0[0])
      tempLon.append($0[1])
    }
    
    /// Zoom to the entire route polyline
    let center = CLLocationCoordinate2D(latitude : (tempLat.min()! + tempLat.max()!) / 2,longitude: (tempLon.min()! + tempLon.max()!) / 2)
    let span = MKCoordinateSpan(latitudeDelta : (tempLat.max()! - tempLat.min()!) * 1.3,longitudeDelta: (tempLon.max()! - tempLon.min()!) * 1.3)
    let region = MKCoordinateRegion(center: center,span: span)
    vcTrainMapView.setRegion(region,animated: true)
  }

解决方法

.map...

var tempLat = slopeLatLonArray.map { $0[0] }
var tempLon = slopeLatLonArray.map { $0[1] }

// Could also zip to vLocations for a 1 liner
var vLocations = zip(tempLat,tempLon).map(CLLocationCoordinate2D.init)

或在初始 for 循环中设置...

var tempLat: [Double] = []
var tempLon: [Double] = []
for index in slopeLatLonArray.indices {
    tempLat[index] = Double(slopeLatLonArray[index][0])
    tempLon[index] = Double(slopeLatLonArray[index][1])
    vLocations.append(CLLocationCoordinate2D(latitude: tempLat[index],longitude: tempLon[index]))
}
,

您不必要地多次迭代所有位置。首先在填充 vLocations 时。第二次填充slopeLatLonArray。获取 tempLat 和 tempLon 最小值和最大值时的第三、第四、第五和第六。再次为跨度获取它们时又进行了 4 次(这可能会被编译器优化,但我不确定)。

我的建议是在填充 vLocations 时在第一次迭代期间获取所有这些值。这样,您将只迭代所有位置一次:

func drawFullRouteOverlay() {
    guard let first = slopeLatLonArray.first,first.count == 2 else { return }
    var minLatitude = first[0]
    var maxLatitude = first[0]
    var minLongitude = first[1]
    var maxLongitude = first[1]
    vLocations = slopeLatLonArray.map {
        let latitude = $0[0]
        let longitude = $0[1]
        minLatitude = min(minLatitude,latitude)
        maxLatitude = max(maxLatitude,latitude)
        minLongitude = min(minLongitude,longitude)
        maxLongitude = max(maxLongitude,longitude)
        return .init(latitude: latitude,longitude: longitude)
    }
    /// Draw the resulting polyline
    let polyline = MKPolyline(coordinates: vLocations,count: vLocations.count)
    vcTrainMapView.addOverlay(polyline)
    
    /// Zoom to the entire route polyline
    let center = CLLocationCoordinate2D(latitude: (minLatitude + maxLatitude) / 2,longitude: (minLongitude + maxLongitude) / 2)
    let span = MKCoordinateSpan(latitudeDelta: (maxLatitude - minLatitude) * 1.3,longitudeDelta: (maxLongitude - minLongitude) * 1.3)
    let region = MKCoordinateRegion(center: center,span: span)
    vcTrainMapView.setRegion(region,animated: true)
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。