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-解析数组的作者接下来又提供了他本人实现的Dictonary
的value
求合实现!但是,请原谅我没有耐心看完那一大段代码。 而是通过参考Array
的做法,实现更加简洁的Dictionary
的value
合值
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
来取值!
那么Dictonary
的key
拼接也可以相应的实现了,同时,正序倒序也可以参考如下代码理解
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))
最后
手贱的打印了一下字典的keys
和values
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时间并不长,所以某些地方可能有误,如果发现,请及时告知。
本文为原创文章,未经本人同意,禁止转载
网友评论