Swift写地图,长度,过滤为减少

时间:2015-09-30 18:48:06

标签: swift function

作为练习,我尝试将地图,长度和过滤器写为reduce函数。

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

这是我可以用来将这些函数重写为reduce的最优雅的语法吗? 第二个问题:地图采用函数f:(T-> T) 基本上类型说我只能返回T类型的东西,但如果我写的函数将类型T转换为Bool,或者Int ... 我该如何做到这一点? 好像地图不存在

2 个答案:

答案 0 :(得分:7)

对于将类型T转换为(可能不同的)类型S的映射 只需使用两个类型的占位符:

func map<T, S>(array: [T], f: (T->S)) -> [S] {
    return array.reduce([]) {
        (var seed, value) in
        seed.append(f(value))
        return seed
    }
}

示例:

let x = map([1, 2, 3], f: { String($0) })
print(x) // ["1", "2", "3"]

这个“是否是最优雅的语法”也是一个 个人意见问题。如果您替换append()方法 通过数组连接+,然后seed参数需要 不可变:

func map<T, S>(array: [T], f: (T->S)) -> [S] {
    return array.reduce([]) {
        (seed, value) in
        seed + [f(value)]
    }
}

可以使用简写参数名称

编写
func map<T, S>(array: [T], f: (T->S)) -> [S] {
    return array.reduce([]) { $0 + [ f($1) ] }
}

类似地:

func filter<T>(array: [T], predicate: (T->Bool)) -> [T]{
    return array.reduce([]) { predicate($1) ? $0 + [ $1 ] : $0 }
}

请注意map()filter()的实施使用 reduce()(而不是循环)非常无效,因为在每个缩减步骤中都会创建新数组。参见例如

进行分析。对于练习(如你所说),这很好,只是 不要在生产中使用这样的东西。)

答案 1 :(得分:0)

扩展名CollectionType

extension CollectionType {
func MyMap<T>(transform: (Self.Generator.Element) -> T) -> [T] {
    let list = self.reduce([T]()) { (var seed, value) in
        seed.append(transform(value))
        return  seed
    }
    return list
}}

然后使用[1,2,3] .MyMap({$ 0 + 1})