map这东西在oc中并未用过,但是swift在处理数组的时候显得格外的游刃有余,这归功于map这个函数;

map函数  arr.map(<#T##transform: (Int) throws -> T##(Int) throws -> T#>) 其获取一个闭包表达式作为唯一参数,集合中的每个元素调用一次该闭包函数,并返回该元素所映射的值(也可以是不同类型的值)。具体的映射方式和返回值类型由闭包来指定。

关于map,swift开发者大会唐巧有一片关于Monat的演讲,对map的解释笔者觉得很精髓,map就是把一个盒子拆开,取出盒子里面的元素,把盒子里面的元素进行一系列的运算,然后再放回盒子的这么个过程。

下面举出一个map函数的执行实例:

  1. //map 方法
  2.  
  3. let array = [1,2,3,4]
  4. let newArray = array.map { (element:Int) -> String in
  5. let string = String.init(format: "%d", element)
  6. return string
  7. }
  8.  
  9. print(newArray)
  10.  
  11. let newArray2 = array.map({
  12. "\($0+10)"
  13.  
  14. })
  15.  
  16. print(newArray2)

element代表数组中的每一个元素,Int是初始类型 ,String是要转换的类型,in后是操作方法  newArrray返回一个元素是4个字符串的数组["1","2","3","4"];

下面的方法是闭包的形式对数组进行操作,对数组中的每一个元素➕10然后转换成字符串;希望各位先去理解下闭包;


 flatmap函数

说到map函数,自然要谈一下flatmap,flatmap和map函数基本类似,但是存在着其他的区别;

map 可以对一个集合类型的所有元素做一个映射操作。 那么 flatMap 呢?

  1. let numbers = [1 ,2, 3]
  2.  
  3. let resultMap = numbers.map({$0 + 2})
  4. print(resultMap)//[3, 4, 5]
  5.  
  6. let result = numbers.flatMap { $0 + 2 }
  7.  
  8. print(result)//[3, 4, 5]

可见,我对numbers进行map和flatmap操作返回的值是一模一样的,也就是说flatmap同样对数组进行了映射操作,但是区别到底在哪里呢?

  1. let numbers2 = [[1 ,2, 3],[4 , 5 ,6]]
  2. let resultMap2 = numbers2.map({$0.map({$0 + 2})})
  3. print(resultMap2)//[[3, 4, 5], [6, 7, 8]]
  4.  
  5. let resultFlatmap2 = numbers2.flatMap({$0.map({$0 + 2})})
  6.  
  7. print(resultFlatmap2)//[3, 4, 5, 6, 7, 8]

可见, flatMap 依然会遍历数组的元素,并对这些元素执行闭包中定义的操作。 但唯一不同的是,它对最终的结果进行了所谓的 “降维” 操作。 本来原始数组是一个二维的, 但经过 flatMap 之后,它变成一维的了。

具体的原理可以去查询一下flatmap的定义,flatmap函数有连个重载,并且通过result.append(contentsOf:)将结果元素添加到了新的数组中,成为了一个一维数组;

flatMap 的另一个重载
我们来看一个例子:

  1. let optionalArray: [String?] = ["AA", nil, "BB", "CC"];
  2. var optionalResult = optionalArray.flatMap{ $0 }
  3. print(optionalResult)// ["AA", "BB", "CC"]

这样竟然没有报错, 并且 flatMap 的返回结果中, 成功的将原数组中的 nil 值过滤掉了。 再仔细观察,你会发现更多。 使用 flatMap 调用之后, 数组中的所有元素都被解包了, 如果同样使用 print 函数输出原始数组的话, 会得到这样的结果:

  1. let optionalArray: [String?] = ["AA", nil, "BB", "CC"];
  2. var optionalResult = optionalArray.flatMap{ $0 }
  3. print(optionalResult)// ["AA", "BB", "CC"]
  4. print(optionalArray) //[Optional("AA"), nil, Optional("BB"), Optional("CC")]

也就是说原始数组的类型是 [String?] 而 flatMap 调用后变成了 [String]。 这也是 flatMap 和 map 的一个重大区别。 如果同样的数组,我们使用 map 来调用, 得到的是这样的输出:

[Optional("AA"), nil, Optional("BB"), Optional("CC")]

这就和原始数组一样了。 这两者的区别就是这样。 map 函数值对元素进行变换操作。 但不会对数组的结构造成影响。 而 flatMap 会影响数组的结构。再进一步分析之前,我们暂且这样理解。

flatMap 的这种机制,而已帮助我们方便的对数据进行验证,比如我们有一组图片文件名, 我们可以使用 flatMap 将无效的图片过滤掉:
究竟flatmap是如何过滤掉nil的呢?感兴趣的还是自己去查吧

你需要知道的swift必备函数 map的更多相关文章

  1. 对于JavaScript的函数.NET开发人员应该知道的11件事

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 昨天小感冒今天重感冒,也不能长篇大论.如果你是.NET开发人员,在进入前端开发领域的时候,对 ...

  2. 很少有人知道的c++中的try块函数

    c++有一些在现实世界中很少看到的结构.这些结构有着自己的用法,但是要特别小心保守的予以运用.就像是网站 The Old New Thing首页标题上面的说的那样: “代码通常被读的次数原因超过了被写 ...

  3. swift中高阶函数map、flatMap、filter、reduce

    Swift相比于Objective-C又一个重要的优点,它对函数式编程提供了很好的支持,Swift提供了map.filter.reduce这三个高阶函数作为对容器的支持. 1 map:可以对数组中的每 ...

  4. 那些必须要知道的Javascript

    原文:那些必须要知道的Javascript JavaScript是前端必备,而这其中的精髓也太多太多,最近在温习的时候发现有些东西比较容易忽略,这里记录一下,一方面是希望自己在平时应用的时候能够得心应 ...

  5. 关于WPF你应该知道的2000件事

    原文 关于WPF你应该知道的2000件事 以下列出了迄今为止为WPF博客所知的2,000件事所创建的所有帖子. 帖子总数= 1,201 动画 #7 - 基于属性的动画 #686 - 使用动画制作图像脉 ...

  6. [技术翻译]您应该知道的13个有用的JavaScript数组技巧

    本次预计翻译三篇文章如下: 01.[译]9个可以让你在2020年成为前端专家的项目 02.[译]预加载响应式图像,从Chrome 73开始实现 03.[译]您应该知道的13个有用的JavaScript ...

  7. 每个JavaScript开发人员应该知道的33个概念

    每个JavaScript开发人员应该知道的33个概念 介绍 创建此存储库的目的是帮助开发人员在JavaScript中掌握他们的概念.这不是一项要求,而是未来研究的指南.它基于Stephen Curti ...

  8. 关于Java高并发编程你需要知道的“升段攻略”

    关于Java高并发编程你需要知道的"升段攻略" 基础 Thread对象调用start()方法包含的步骤 通过jvm告诉操作系统创建Thread 操作系统开辟内存并使用Windows ...

  9. 【转载】在IT界取得成功应该知道的10件事

     在IT界取得成功应该知道的10件事 2011-08-11 13:31:30 分类: 项目管理 导读:前面大多数文章都是Jack Wallen写的,这是他的新作,看来要成为NB程序员还要不停的自我总结 ...

随机推荐

  1. Android 布局优化

    转载自stormzhang的博客:http://stormzhang.com/android/2014/04/10/android-optimize-layout/ < include /> ...

  2. Flask生成SECRET_KEY(密钥)的一种简单方法

    SECRET_KEY是Flask中比较重要的一个配置值.本文介绍一种比较简单的生成SECRET_KEY的方法. Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值,这是一 ...

  3. system_call的处理过程

    一. 跟踪time系统调用 使用gdb调试跟踪系统调用内核函数sys_time 过程如下: 对sys_time设置断点之后,在menuOS中执行time命令,发现系统停在systime处,输入S单步执 ...

  4. React Native中的网络请求fetch和简单封装

    React Native中的网络请求fetch使用方法最为简单,但却可以实现大多数的网络请求,需要了解更多的可以访问: https://segmentfault.com/a/1190000003810 ...

  5. OpenSSL - RSA非对称加密实现

    非对称加密:即两端使用一对不同的密钥进行加密. 在非对称加密中,需要两对密钥,公钥和私钥. 公钥个私钥属于对立关系,一把加密后,只有另一把才可以进行解密. 公钥数据加密 数字证书内包含了公钥,在进行会 ...

  6. Javascript 事件(一)

    焦点事件获取焦点事件onfocus \  失去焦点事件 onblur 使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入.我们可以通过一些方式给元素设置焦点    1. ...

  7. [GodLove]Wine93 Tarining Round #3

    比赛链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44857#overview 题目来源: ZOJ Monthly, July 2 ...

  8. B - 搬寝室

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Pract ...

  9. Linux下手动获取当前调用栈

    被问到如何手动获取当前的调用栈,之前碰到过一时没记起来,现在回头整理一下. 其原理是:使用backtrace()从栈中获取当前调用各层函数调用的返回地址,backtrace_symbols()将对应地 ...

  10. Codeforces Round #378 (Div. 2) A B C D 施工中

    A. Grasshopper And the String time limit per test 1 second memory limit per test 256 megabytes input ...