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的资料请关注我们其它相关文章!

(0)

相关推荐

  • Swift无限循环控件开发

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

  • Swift4使用GCD实现计时器

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

  • Swift实现倒计时5秒功能

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

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

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

  • 如何使用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 ,这个方法可以用来设置图形的外观.我们就用这个方法来实现本文中的各种动画. 创

  • 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 去除 TableView 多余的空Cell中的横线的方法

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

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

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

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

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

随机推荐