美文网首页
reduce(_, combine:_)

reduce(_, combine:_)

作者: honzon_0 | 来源:发表于2016-02-18 11:24 被阅读166次

    objc.io blog学习:代码片段 #1-解析数组 中提到了使用递归的来进行求得Array的所有元素合

    extension Array {
        var decompose : (head: T, tail: [T])? {
            return (count > 0) ? (self[0], Array(self[1..<count])) : nil
        }
    }
        
    func sum(xs: [Int]) -> Int {
        if let (head, tail) = xs.decompose {
            return head + sum(tail)
         } else {
           return 0
         }
    }
        
    var xs: [Int] = [1, 2, 3]
    let result = sum(xs)
    result //result=6
    

    但是 但是 但是
    对于一个懒癌晚期的程序员来说,这段代码绝对不是很好的选择。

    刹那间

    记得喵神Swifter 100个 Swift 必备 Tips书中提到过类似写法,最后在可变参数函数tip中找到了该实现,代码如下

    func sum(input: Int...) -> Int {
        return input.reduce(0, combine: +)
    }
    
    print(sum(1,2,3,4,5))
    // 输出:15”
    
    

    那么,Array求和的实现就自然而然的出来了

    var xs: [Int] = [1, 2, 3]
    print(xs.reduce((0), combine:+))
    // 输出:6
        
    var ss: [String] = ["hon", "zon", "-0"]
    print(ss.reduce("", combine:+))
    // 输出:honzon-0
    

    好了,现在巧妙的实现了数组元素求和!问题好像解决了!

    然而

    objc.io blog学习:代码片段 #1-解析数组的作者接下来又提供了他本人实现的Dictonaryvalue求合实现!但是,请原谅我没有耐心看完那一大段代码。 而是通过参考Array的做法,实现更加简洁的Dictionaryvalue合值

    var dic: [String : Int] = [String : Int]()
    dic["1"] = 2
    dic["2"] = 32
    dic["3"] = 2
    dic["4"] = 32
    
    print(dic.reduce(0, combine: {
    //    $0.1.1 + $0.0   //正序 2+2+32+32 = 68
        $0.0 + $0.1.1   //倒序 32+32+2+2 = 68
    }))
    

    这里可能有人就会奇怪了,为什么是$0.1.1,还有 正序 倒序是什么鬼?

    reduce(_, combine:_)API如下

    /// Return the result of repeatedly calling `combine` with an
    /// accumulated value initialized to `initial` and each element of
    /// `self`, in turn, i.e. return
    /// `combine(combine(...combine(combine(initial, self[0]),
    /// self[1]),...self[count-2]), self[count-1])`.
       @warn_unused_result
       public func reduce<T>(initial: T, @noescape combine: (T, Self.Generator.Element) throws -> T) rethrows -> T
    

    通过API可以知道,该方法返回的是一个累积值,计算类型和返回类型是均是T

    而通过Option键可以知道$0的格式为let $0: ((Int, (String, Int))),也就是说实际上传入闭包的参数是(T,(Key,Value))这种样式,这就很好的解释了为什么通过$0.1.1来取值!

    那么Dictonarykey拼接也可以相应的实现了,同时,正序倒序也可以参考如下代码理解

    print(dic.reduce("默认值:", combine: {
    //    $0.1.0 + "|" + $0.0  //3|1|2|4|默认值:
       $0.0 + "|" + $0.1.0  //默认值:|4|2|1|3
    }))
    

    如果T类型是(String,Int),那么,$0的类型是(String, Int)而不会是((String, Int),(String, Int))

    最后

    手贱的打印了一下字典的keysvalues

    class MyClass {
        
    }
    
    struct MyStrut {
        
    }
    
    enum MyEnum {
        case enum1
        case enum2
    }
    
    var anyDic = [String : Any]()
    anyDic["1"] = "1"
    anyDic["2"] = xs
    anyDic["3"] = 2.0
    anyDic["4"] = MyClass()
    anyDic["5"] = MyStrut()
    anyDic["6"] = MyEnum.enum1
    
    print("anyDic.keys:",anyDic.keys)
    print("anyDic.values:",anyDic.values)
    

    结果并不很满意

    anyDic.keys: LazyMapCollection<Dictionary<String, protocol<>>, String>(_base: ["4": Swift实践1.MyClass, "2": [1, 2, 3], "1": "1", "5": Swift实践1.MyStrut(), "6": Swift实践1.MyEnum.enum1, "3": 2.0], _transform: (Function))
    anyDic.values: LazyMapCollection<Dictionary<String, protocol<>>, protocol<>>(_base: ["4": Swift实践1.MyClass, "2": [1, 2, 3], "1": "1", "5": Swift实践1.MyStrut(), "6": Swift实践1.MyEnum.enum1, "3": 2.0], _transform: (Function))
    

    既然正好在学习reduce(_, combine:_)方法,那么就用它实现了一下自己想要的结果

    extension Dictionary {
       var allKeys: [Any] {
            return self.reduce([Any](), combine: {
                [$0.1.0] + $0.0
            })
        }
        
        var allValues: [Any] {
            return self.reduce([Any](), combine: {
                [$0.1.1] + $0.0
            })
        }
    }
    print("\n")
    print("anyDic.allKeys:",anyDic.allKeys)
    print("anyDic.allValues:",anyDic.allValues)
    

    打印结果

    anyDic.allKeys: ["3", "6", "5", "1", "2", "4"]
    anyDic.allValues: [2.0, Swift实践1.MyEnum.enum1, Swift实践1.MyStrut(), "1", [1, 2, 3], Swift实践1.MyClass]
    

    因为学习Swift时间并不长,所以某些地方可能有误,如果发现,请及时告知。

    本文为原创文章,未经本人同意,禁止转载

    相关文章

      网友评论

          本文标题:reduce(_, combine:_)

          本文链接:https://www.haomeiwen.com/subject/rgpmkttx.html