Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

Simplify this foreach loop (to find min/max in a nested array) in swift

I would love to get rid of the foreach loop. Currently I am doing a foreach loop to populate a temp variable to separate my array to get the min/max for each Lat/Lon.

eg: 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)
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are unnecessarily iterating all your locations multiple times. First when populating vLocations. Second when populating slopeLatLonArray. Third, fourth, fifth and sixth when getting tempLat and tempLon minimum and maximum values. And another 4 times when getting them again for the span (this might be optimized by the compiler but I am not sure).

What I suggest is to get all those values during the first iteration when populating vLocations. This way you will iterate all locations only once:

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)
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...