Skip to content

Instantly share code, notes, and snippets.

@manmal
Last active September 12, 2015 19:10
Show Gist options
  • Select an option

  • Save manmal/a5d3ee15bf5ed65ddecc to your computer and use it in GitHub Desktop.

Select an option

Save manmal/a5d3ee15bf5ed65ddecc to your computer and use it in GitHub Desktop.
Functional Nerdgasm in Swift
typealias DistanceRange = (from: Double, to: Double) // meters
typealias WaterListResult = (water: Water, lodging: Lodging, distance: Double, price: Float?)
typealias LodgingAndDistance = (lodging: Lodging, distance: Double?)
extension Water {
// Returns waters that are sorted by their nearest (nearest to `center`) lodging's distance to `center`.
static func watersByProximity(distanceRange: DistanceRange, center: CLLocation) -> [WaterListResult] {
return ModelsStorage.waters
.flatMap { (water: Water) -> [WaterListResult] in // Map to water's lodgings combined with their distances to center
if let lodgings = water.lodgings {
let lodgingAndDistance = lodgings
.map { return LodgingAndDistance($0, $0.coordinates?.distanceTo(center)) } // attach distances to lodgings
.filter { return $0.1 != nil } // filter those with non-nil distance
.map { (lD: LodgingAndDistance) -> LodgingAndDistance in // force-unwrap filtered non-nil distances
return LodgingAndDistance(lD.lodging, lD.distance!)
}
.filter { (lD: LodgingAndDistance) -> Bool in // filter those that are within distanceRange
return lD.distance >= distanceRange.from && lD.distance < distanceRange.to
}
.sort({ $0.distance < $1.distance }) // sort lodgings of this water by distance
.first // select only first lodging
if let foundLodgingAndDistance = lodgingAndDistance {
return [WaterListResult(water: water, lodging: foundLodgingAndDistance.lodging, distance: foundLodgingAndDistance.distance!, price: nil)]
}
}
return [] // found no lodgings for this water
}
.sort({ $0.distance < $1.distance }) // sort ALL lodgings by their distance
}
}
@Noobish1
Copy link

another option is this;

extension Water {
    // Returns waters that are sorted by their nearest (nearest to `center`) lodging's distance to `center`.
    static func watersByProximity(distanceRange: DistanceRange, center: CLLocation) -> [WaterListResult] {
        let toResults = { water in
            return water.lodgings
                .flatMap { LodgingAndDistance(lodging: $0, distance: $0.coordinates?.distanceTo(center)) } // attach distances to lodgings, filtering out nils
                .filter { $0.distance >= distanceRange.from && $0.distance < distanceRange.to } // filter those that are within distanceRange
                .sort { $0.distance < $1.distance } // sort lodgings of this water by distance
                .first // select only first lodging
                .map { WaterListResult(water: water, lodging: $0.lodging, distance: $0.distance, price: nil) }
        }

        return ModelsStorage.waters.flatMap(toResults).sort { $0.distance < $1.distance } // sort ALL WaterListResults by their distance
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment