Swift 进阶 - map 和 flatMap的使用

map 和 flatMap 主要分在集合上的使用和在可选类型上的使用,下面分别来看下。

集合上使用 map 和 flatMap

先看如下的代码:

func getInfos(by name: String) -> [String] {
 if name == "Jack" {
  return ["Male", "25", "New York"]
 } else if name == "Lucy" {
  return ["Female", "18", "London"]
 } else {
  return ["Unkown", "Unkown", "Unkown"]
 }
}

let names = ["Jack", "Lucy", "Nobody"]

let infos1 = names.map { getInfos(by: $0) }
print(infos1)

let infos2 = names.flatMap { getInfos(by: $0) }
print(infos2)

输入是一个一维数组,转换后 infos1 的结果是如下的一个二维数组,所以 map 后有两层结构:

[["Male", "25", "New York"], ["Female", "18", "London"], ["Unkown", "Unkown", "Unkown"]]

输入是一个一维数组,转换后 infos2 的结果是如下的一个一维数组,所以 flatMap 后只有一层结构:

["Male", "25", "New York", "Female", "18", "London", "Unkown", "Unkown", "Unkown"]

map 在 Array 上的实现大致如下:

extension Array {
 func map<T>(_ transform: (Element) -> T) -> [T] {
  var result: [T] = []
  for x in self {
   result.append(transform(x))
  }
  return result
 }
}

flatMap 在 Array 上的实现大致如下:

extension Array {
 func flatMap<T>(_ transform: (Element) -> [T]) -> [T] {
  var result: [T] = []
  for x in self {
   result.append(contentsOf: transform(x))
  }
  return result
 }
}

可选类型上使用 map 和 flatMap

如下代码中,输入是 stringNumbers.first,其类型是 String?

  • 转换后 x 的类型是 Int??,所以 map 后有两层 Optional
  • 转换后 y 的类型是 Int?,所以 flatMap 后只有一层 Optional
let stringNumbers = ["1", "2", "3", "foo"]
let x = stringNumbers.first.map { Int($0) } // Optional(Optional(1))
let y = stringNumbers.first.flatMap { Int($0) } // Optional(1)

map 在 Optional 上的实现大致如下:

extension Optional {
 func map<U>(transform: (Wrapped) -> U) -> U? {
  if let value = self {
   return transform(value)
  }
  return nil
 }
}

flatMap 在 Optional 上的实现大致如下:

extension Optional {
 func flatMap<U>(transform: (Wrapped) -> U?) -> U? {
  if let value = self, let transformed = transform(value) {
   return transformed
  }
  return nil
 }
}

以上就是Swift 进阶 - 详解map 和 flatMap的详细内容,更多关于Swift map 和 flatMap的资料请关注我们其它相关文章!

时间: 2020-08-29

swift4.2实现新闻首页导航

对于仿照新闻首页的页面,已经有比较好用的OC版本,现在我们来写一个swift版本的. 设备:xcode 10.2     语言:swift 4.2 效果图: 我们先创建一个多控制器的导航栏,直接上代码: // // JHSBarItemView.swift // ScrollBarController // // Created by yaojinhai on 2019/4/15. // Copyright © 2019年 yaojinhai. All rights reserved. // i

Swift 使用 Observe 监测页面滚动的实现方法

Swift 以前是通过addObserver来实现对某个属性的变化监听,而最新的变化,书写起开更加方便. observer = test.observe(\.field, options: [.new, .initial]) { (object, change) in print(change) } 一定要用属性赋值当前的 observe 结果,没有的话可能会造成 change 不生效. 对 UIScrollView 的滚动监听,我们可以使用UIScrollViewDelegate extens

Swift 去除 TableView 多余的空Cell中的横线的方法

在使用 UITableViewController 的时候,多余的空 cell 会默认展示很多横线. 如何去除呢? 给 footerHeight 反一个极小的值就可以了 override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return 0.001 } 结果 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们.

如何使用Swift来实现一个命令行工具的方法

本文即简单介绍了如何在Swift中开发命令行工具,以及与Shell命令的交互.水文一篇,不喜勿喷. 主要是使用该工具来解析微信的性能监控组件Matrix的OOM Log. 基本模块 这里,仅简单介绍了常见的基本模块. Process Process类可以用来打开另外一个子进程,并监控其运行情况. launchPath:指定了执行路径.如可以设置为 /usr/bin/env ,这个命令可以用于打印本机上所有的环境变量:也可以用于执行shell命令,如果你接了参数的话.本文的Demo就用它来执行输入

SwiftUI使用Paths和AnimatableData实现酷炫的颜色切换动画

老铁们,是时候燥起来了!本文中我们将学习如何使用 SwiftUI 中的 Paths 和 AnimatableData 来制作颜色切换动画. 这些快速切换的动画是怎么实现的呢?让我们来看下文吧! 基础 要实现动画的关键是在 SwiftUI 中创建一个实现 Shape 协议的结构体.我们把它命名为 SplashShape .在 Shape 协议中,有一个方法叫做 path(in rect: CGRect) -> Path ,这个方法可以用来设置图形的外观.我们就用这个方法来实现本文中的各种动画. 创

Swift 5.1 之类型转换与模式匹配的教程详解

类型转换在Swift中使用 is 和 as 操作符实现. 类型检查 使用操作符 is 检查一个实例是否是某个确定的类以及其继承体系的父类或子类类型.如果是某个确定的类(该类继承体系的父类或子类)类型,则返回 true ,否则返回 false . class Cat { func hairColor() -> String { return "五颜六色" } } class WhiteCat: Cat { override func hairColor() -> String

Swift实现倒计时5秒功能

一般在项目的"引导页"有个功能,倒计时5秒结束后,然后可以允许用户点击跳过按钮跳过引导页.同样在"登录"和"注册"页面也有类似功能,发送验证码后,计时60秒后才允许用户再次请求重新发送验证码. 计时方式一(sleep + performSelector) 通过调用sleep(1)阻塞线程的方式来达到目的 import UIKit class GAPublishViewController: GABaseViewController { var j

iOS SwiftUI 颜色渐变填充效果的实现

SwiftUI 为我们提供了各种梯度选项,所有这些选项都可以通过多种方式使用. Gradient 渐变器 A color gradient represented as an array of color stops, each having a parametric location value. gradient是一组颜色的合集,每个颜色都忽略位置参数 LinearGradient 线性渐变器 线性渐变器拥有沿轴进行渐变函数,我们可以自定义设置颜色空间.起点和终点. 下面我们看看Linear

Swift4使用GCD实现计时器

开发过程中,我们可能会经常使用到计时器.苹果为我们提供了Timer.但是在平时使用过程中会发现使用Timer会有许多的不便 1:必须保证在一个活跃的runloop,我们知道主线程的runloop是活跃的,但是在其他异步线程runloop就需要我们自己去开启,非常麻烦. 2:Timer的创建和销毁必须在同一个线程.跨线程就操作不了 3:内存问题.可能循环引用造成内存泄露 由于存在上述问题,我们可以采用GCD封装来解决. import UIKit typealias ActionBlock = ()

Swift无限循环控件开发

无限循环控件是一个常常用到的一个控件,尤其是一些广告或者应用内容公告通知,或者新闻滚动的设计,都是必备的.这种控件网上也有很多,也有很多可以自定义的版本,功能非常强大. 但对于我们开发者来说,在具体的应用上风格和样式都是比较统一的,一般只需要自己特定的一种风格或样式即可,引入第三方显然有点大材小用.那么我们怎么能简单而且又快速的造一个无限循环的控件呢,只要我们知道无限循环的原理,那么我们就很自由的按照需求快速的完成.今天我们就讲讲这个'造轮'过程. 首先我们简单分析一下无限循环的原理.一个控件的

ASP.NET 控件开发系列之图片切换web控件

贴出来控件页面的代码. PicList.ascx 复制代码 代码如下: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="PicList.ascx.cs" Inherits="WebParts_PicList" %> <style type="text/css"> /* Reset style */ * { marg

控件开发时两种JS嵌入资源方式的使用方法

第一种: 直接把要嵌入的JS文件属性设置为"嵌入的资源".protected override void OnInit(EventArgs e) {       base.OnInit (e);        if(!base.Page.IsStartupScriptRegistered("Script"))         {                 Assembly assembly = typeof(TestControl).Assembly;    

使用VS2010 C#开发ActiveX控件(上)

要开发Web版的读卡程序,大体思路如下: 1.       使用C#对原始的Dll进行封装,这里要封装两部分内容,一部分是串口通信的功能,一部分是对卡读写的功能. 2.       开发ActiveX控件调用封装后的Dll,使用串口通信来对卡进行读写. 3.       打包并发布ActiveX控件. 4.  使用ActiveX控件. 思路1中封装代码有2个类SerialInterfaceHelper,串口通信的帮助类,MifareOneHelper,M1卡的读写帮助类,我们放在了项目CardR

Repeater控件与PagedDataSource结合实现分页功能

本文讲解Repeater控件与PagedDataSource相结合实现其分页功能.PagedDataSource 类封装那些允许数据源控件(如 DataGrid.GridView)执行分页操作的属性.如果控件开发人员需对自定义数据绑定控件提供分页支持,即可使用此类. PagedDataSource 类的部分公共属性: AllowCustomPaging // 获取或设置指示是否启用自定义分页的值. AllowPaging // 获取或设置指示是否启用分页的值. Count // 获取要从数据源使

C#实现多选项卡的浏览器控件

本文详细为大家分享了C#多选项卡的浏览器控件的设计与实现,供大家参考,具体内容如下 1.  为什么我们需要多选项卡的浏览器控件 项目中需要使用WinForm应用程序来包装BS应用程序的浏览器外壳,在.NET的WebBrowser中没有多选项卡浏览的自带配置属性,我们需要实现多选项卡的浏览器控件来实现包装BS应用程序的目的,而不会弹出IE浏览器窗口. 2. 我们需要了解哪些知识点 2.1.     WebBrowser控件 WebBrowser 控件为 WebBrowser ActiveX 控件提

JS 控件事件小结

概述: 事件对于控件来说至关重要,控件的消息通信机制使用事件的成本最低,但是对于JS控件来说有一些麻烦需要解决,JS类本身不支持事件,DOM模型支持的事件仅适应于浏览器的DOM节点.所以创建一套事件是我们写控件之前要做的. 事件机制 对于事件的机制我不想多说,各种语言中对事件的描述都很具体,都是观察者模式的一种实现,我们可以从中抽取出事件必须的接口(由于控件库是基于jQuery 所以接口跟jquery保持一致): 1.on: 绑定事件 2.off: 删除事件 3.fire: 触发事件 4.add

Android仿京东淘宝自动无限循环轮播控件思路详解

在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于RelativeLayout,首先要考虑的就是自定义的控件需要扩展那些属性,把这些属性列出来.在这里是要实现类似于京东淘宝的无限轮播广告栏,那么首先想到的就是轮播的时长.轮播指示器的样式等等.我在这里列举了一些并且结合到了代码中. 1.扩展属性 (1)是否开启自动轮播的功能. (2)指示器的图形样式,一

Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件

最近用到需要无限轮播自动播放的轮播轮播图,网上感觉都有这样那样的问题,于是自己写了一个通用的控件CarouselFigureView. 特点: 1.可以轮播view可以自己定义,不一定是要是ImageView2.指示器默认显示,但是可以隐藏3.可以设置指示器的颜色.间距.大小 4.有基础的可以自己修改代码改变指示器位置,这个应该不难5.可以自己开启和关闭自动轮播,开启轮播的时候可以设置轮播时间间隔,默认3000毫秒 我们先来看看效果图: 然后来看看使用代码 xml代码 <?xml version

RecyclerView+SnapHelper实现无限循环筛选控件

项目用到横向滑动的单项选择控件.需求如下: 1.选项由后台配置,也就是控件要动态设置宽度:2.每次滑动都要左对齐,并默认选中最左边选项:3.控件可以无限循环. 动态设置控件宽度:获取adapter的item宽度:获取adapter里装载的itemCount. 每次滑动都要左对齐:利用LinearSnapHelper中calculateDistanceToFinalSnap的方法实现: 默认选中最左item:利用RecycleView的LayoutManager中查找显示第一项的方法linearM