Skip to content

Instantly share code, notes, and snippets.

@natan
Last active February 2, 2022 22:46
Show Gist options
  • Save natan/3032f0fd43fb79b729f6 to your computer and use it in GitHub Desktop.
Save natan/3032f0fd43fb79b729f6 to your computer and use it in GitHub Desktop.
Simultaneous map and filter in Swift
extension Array {
// Similar to Lisp's map function that allows returning nil in the transform to omit the item from the resulting array.
func mapAndFilter<U>(transform: (T) -> U?) -> U[] {
var results = U[]()
for item in self {
if let transformedItem = transform(item) {
results.append(transformedItem)
}
}
return results
}
}
// Examples
struct City {
var name = ""
var state = ""
var inCalifornia: Bool {
return state == "CA"
}
}
var cities = [City(name: "San Francisco", state: "CA"), City(name: "Portland", state: "OR"), City(name: "Seattle", state: "WA")]
// 1. Say you wanted to get all the city names matching a certain condition with just map() and filter().
let californianCities = cities.filter {
(city: City) -> Bool in
return city.inCalifornia
}
let californianCityNames = californianCities.map {
(city: City) -> String in
return city.name
}
// 2. With mapAndFilter() it is more expressive as they're combined into one transformation:
let californianCityNames2 = cities.mapAndFilter {
(city: City) -> String? in
return city.inCalifornia ? city.name : nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment