As an exercise, I'm trying to write map, length and filter as a reduce function.
func map<T>(array: [T], f: (T->T)) -> [T] {
return array.reduce([]) {
(var seed, value) in
seed.append(f(value))
return seed
}
}
func length<T>(array: [T]) -> Int {
return array.reduce(0){ (x,_) in x + 1 }
}
func filter<T>(array: [T], predicate: (T->Bool)) -> [T]{
return array.reduce([]){
(var seed, value) in
if predicate(value){
seed.append(value)
}
return seed
}
}
Is this the most elegant syntax I can use to rewrite those functions as reduce? 2nd question: map takes a function f:(T->T) Basically the type says I can only return something of type T, but what if the function I write transforms type T to a Bool, or and Int... How do I accomplish this? Seems like map doesn't exist
For a mapping which transforms a type T
into a (possibly different) type S
simply use two type placeholders:
func map<T, S>(array: [T], f: (T->S)) -> [S] {
return array.reduce([]) {
(var seed, value) in
seed.append(f(value))
return seed
}
}
Example:
let x = map([1, 2, 3], f: { String($0) })
print(x) // ["1", "2", "3"]
Whether this "is this the most elegant syntax" is also a
matter of personal opinion. If you replace the append()
method
by array concatenation with +
then the seed
parameters needs
not be variable:
func map<T, S>(array: [T], f: (T->S)) -> [S] {
return array.reduce([]) {
(seed, value) in
seed + [f(value)]
}
}
Which can be written with shorthand parameter names as
func map<T, S>(array: [T], f: (T->S)) -> [S] {
return array.reduce([]) { $0 + [ f($1) ] }
}
Similarly:
func filter<T>(array: [T], predicate: (T->Bool)) -> [T]{
return array.reduce([]) { predicate($1) ? $0 + [ $1 ] : $0 }
}
Just note that an implementation of map()
and filter()
using
reduce()
(instead of a loop) is quite ineffective because a new array is created in each reduction step. See for example
for an analysis. For an exercise (as you said) it is fine, just don't use something like this in production).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With