Why Coding Like this -------map函数揭秘
title: “Why coding like This —— Map 函数揭秘” 1.Map函数揭秘Topic 1:请用Map函数实现对一个Int类型数组的元素进行2倍放大。 Example://例一
let intArray = [1,2,3]
var result = intArray.map{ $0 * 2} //输出[2,4,6]
why coding like this?假设让你写一个函数,传入参数为Int类型数组,对数组内每一个元素进行放大2倍操作,然后将处理后的数组作为结果返回。 //例二:
func doubleArrayByTwo(xs:[Int])->[Int]{
var result :[Int] = []
for x in xs{
result.append(x * 2)
}
return result
}
不妨来试试写的函数: result = doubleArrayByTwo(intArray) //返回[2,6]
看来我们确实实现了对一个数组元素进行放大两倍的函数,那么接下来请实现对每一个数组元素进行一个线性变换(y = ax + b),其中 a = 2 b = 3 。 难度不大,重写一个函数: //例三:线性变换 y = 2x + 3
func linealMeasureArray(xs:[Int])->[Int]{
var result :[Int] = []
for x in xs{
result.append(x * 2 + 3) //仅仅只是括号中的代码改变了下而已
}
return result
}
那么接下来 a = 3 b = 4呢,你开始抓狂,Oh,No!显然每一次a,b值的改变就要重写一个函数绝非明智,考虑到所给命题我们均可以通过 //例四:
func handleIntArray(xs:[Int],f:Int->Int)->[Int]{
var result :[Int] = []
for x in xs {
result.append(f(x))
}
return result
}
值得注意得是,我们除了传入一个xs数组外,还传入了一个 现在来测试下所写的这个函数是否满足我们要求: //输出 3 5 7
result = handleIntArray(intArray){
x in
return 2 * x + 1 //2 * x + 1 就是闭包的处理体
}
可能如此写法仍然让人迷惑,因此我决定再简单分解下。首先声明一个函数名位 func handleClosure(x:Int)->Int{
return 2 * x + 1
}
result = handleIntArray(intArray,handleClosure)
新命题:对Int类型数组的每一个元素进行判断,偶数为 分析:奇偶判断我们通过 x % 2 == 0 语句轻松实现,然后调用handleIntArray即可,遗憾的是闭包的返回参数与我们的不匹配,我们所期望的是返回Bool类型,而闭包中为Int,不得已我们需要重新构建一个 //例五:
func handleBoolArray(xs:[Int],f:Int->Bool)->[Bool]{
var result :[Bool] = []
for x in xs {
result.append(f(x))
}
return result
}
现在我们能够使用 仔细分析两个handle函数,它们看起来非常相似,唯一的区别就是在传入参数上。这时候我们就要试想了,如何声明一个函数能表示不同类型的参数输入呢? 感谢Swift提供了 //例六:
func genericComputeArray<U>(xs:[Int],f:Int->U)->[U]{
var result :[U] = []
for x in xs {
result.append(f(x))
}
return result
}
泛型并不难,注意几点,尖括号
为了使得函数更通用,尝试稍微修改以上函数来构建我们的 //例七:
func myMap<T,U>(xs:[T],f:T->U)->[U]{
var result:[U] = []
for x in xs{
result.append(f(x))
}
return result
}
myMap(intArray){
x in x * 2
}//输出 [2,6]
至于为什么系统的调用是xxx.map{},其实map函数是作为数组的实例方法存在,遵循了协议实现罢了。好奇的你可以一试。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |