Tuesday, June 16, 2015

Map, Filter, Reduce in Swift

With Swift, iOS and Mac developers have map, filter, and reduce methods on arrays. These methods can replace almost all uses of for-in-loops, and are more clear and concise.



map_filter_reduce.swift    Select all
let words = ["angry", "hungry", "aardvark", "aardwolf"] func concatenate(xs: [String]) -> String { var result: String = "" for x in xs { result += x + " " } return result.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()) } concatenate(words) // "angry hungry aardvark aardwolf" println("GRR!! " + words .filter {$0.hasSuffix("gry")} .map {$0.uppercaseString} .reduce("HULK") {"\($0) \($1)"} + "!!!" ) // "GRR!! HULK ANGRY HUNGRY!!!" let numbers = [ 10000, 10303, 30913, 50000, 100000, 101039, 1000000 ] println( numbers .filter { $0 % 2 == 0 } .map { NSNumberFormatter.localizedStringFromNumber($0, numberStyle: .DecimalStyle) } .reduce("") { countElements($0) == 0 ? $1 : $0 + " " + $1 } ) // "10,000 50,000 100,000 1,000


Updated for Swift 3.0 syntax below

map_filter_reduce.swift    Select all
let words = ["angry", "hungry", "aardvark", "aardwolf"] func concatenate(_ xs: [String]) -> String { var result: String = "" for x in xs { result += x + " " } return result.trimmingCharacters(in: .whitespaces) // Xcode 8 beta 6 // return result.trimmingCharacters(in: NSCharacterSet.whitespaces()) // Xcode 8 beta 1 } concatenate(words) // "angry hungry aardvark aardwolf" print("GRR!! " + words .filter {$0.hasSuffix("gry")} .map {$0.uppercased()} .reduce("HULK") {"\($0) \($1)"} + "!!!" ) // "GRR!! HULK ANGRY HUNGRY!!!" let numbers = [ 10000, 10303, 30913, 50000, 100000, 101039, 1000000 ] print( numbers .filter { $0 % 2 == 0 } .map { NumberFormatter.localizedString(from: ($0 as NSNumber) , number: .decimal) } // Xcode 8 beta 6 // .map { NumberFormatter.localizedString(from: $0, number: .decimal) } //Xcode 8 beta 1 .reduce("") { $0.characters.count == 0 ? $1 : $0 + " " + $1 } ) // "10,000 50,000 100,000 1,000




No comments: