reduce(_, combine:_)

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

extension Array {
    var decompose : (head: T, tail: [T])? {
        return (count > 0) ? (self[0], Array(self[1.. 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(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>, 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>, 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:_))