当前位置: 首页 > 知识库问答 >
问题:

Swift中平面图和压缩图的区别

濮佑运
2023-03-14

似乎在Swift 4.1平面图中已弃用。但是在Swift 4.1compactMap中有一个新方法正在做同样的事情?使用平面图,您可以转换集合中的每个对象,然后删除任何为nil的项目。
喜欢平面图

let array = ["1", "2", nil] 
array.flatMap { $0 } // will return "1", "2"

像compactMap

let array = ["1", "2", nil] 
array.compactMap { $0 } // will return "1", "2"

compactMap也在做同样的事情。

这两种方法有什么区别?为什么苹果决定重命名该方法?

共有3个答案

亢奇
2023-03-14

高阶函数-是由参数中的另一个函数操作或/或返回的函数。例如-排序、映射、筛选、减少。。。

map vs compactMap vs flatMap

[RxJava地图vs FlatMap]

  • map-转换(可选,序列,字符串)
  • compactMap-删除nil(数组)
  • 平面图-扁平难结构成单一(可选,集合)

flatMapvscompactMap

在Swift v4.1之前,三种平面地图的实现都有一席之地(没有紧凑地图)。这种认识是从序列中删除nil的原因。它更多的是关于地图而不是平面地图

实验

//---------------------------------------
//map - for Optional, Sequence, String, Combine
//transform

//Optional
let mapOptional1: Int? = Optional(1).map { $0 } //Optional(1)
let mapOptional2: Int? = Optional(nil).map { $0 } //nil
let mapOptional3: Int?? = Optional(1).map { _ in nil } //Optional(nil)
let mapOptional4: Int?? = Optional(1).map { _ in Optional(nil) } //Optional(nil)

//collection
let mapCollection1: [Int] = [1, 2].map { $0 } //[1, 2]
let mapCollection2: [Int?] = [1, 2, nil, 4].map { $0 } //Optional(1), Optional(2), nil, Optional(4),
let mapCollection3: [Int?] = ["Hello", "1"].map { Int($0) } //[nil, Optional(1)]

//String
let mapString1: [Character] = "Alex".map { $0 } //["A", "l", "e", "x"]




//---------------------------------------
//compactMap(one of flatMap before 4.1) - Array, Combine
//removes nil from the input array

//Collection
let compactMapCollection1: [Int] = [1, 2, nil, 4].compactMap { $0 } //[1, 2, 4]
let compactMapCollection2: [[Int]] = [[1, 2], nil, [3, 4]].compactMap { $0 } //[[1, 2], [3, 4]]




//---------------------------------------
//flatMap - Optional, Collection, Combime

//Optional
let flatMapOptional1: Int? = Optional(1).flatMap { $0 } //Optional(1)
let flatMapOptional2: Int? = Optional(nil).flatMap { $0 } //nil
let flatMapOptional3: Int? = Optional(1).flatMap { _ in nil }
let flatMapOptional4: Int? = Optional(1).flatMap { _ in Optional(nil) }

//Collection
let flatMapCollection1: [Int] = [[1, 2], [3, 4]].flatMap { $0 } //[1, 2, 3, 4]
let flatMapCollection2: [[Int]] = [[1, 2], nil, [3, 4]].flatMap { $0 } //DEPRECATED(use compactMap): [[1, 2], [3, 4]]
let flatMapCollection3: [Int?] = [[1, nil, 2], [3, 4]].flatMap { $0 } //[Optional(1), nil, Optional(2), Optional(3), Optional(4)]
let flatMapCollection4: [Int] = [1, 2].flatMap { $0 } //DEPRECATED(use compactMap):[1, 2]

[Swift可选映射与平面映射]
[Swift Functor,Applicative,Monad]

越嘉树
2023-03-14

有三种不同变体的平面地图。接受返回可选值的闭包的Sequence.flatMap(_:)变体已被弃用。序列和可选上的平面地图(_:)的其他变体保持原样。提案文档中解释的原因是误用。

弃用的平面地图变体功能在新方法compactMap下完全相同。

在此处查看详细信息。

禄俊逸
2023-03-14

Swift标准库为flatMap函数定义了3个重载:

Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element]  
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?  
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]  

最后一个重载函数有两种误用方式:
请考虑以下结构和数组:

struct Person {
  var age: Int
  var name: String
}  

let people = [
  Person(age: 21, name: "Osame"),
  Person(age: 17, name: "Masoud"),
  Person(age: 20, name: "Mehdi")
]

第一种方法:附加包装和展开:
如果您需要获取数组中包含的人员年龄数组,您可以使用两个函数:

let flatMappedAges = people.flatMap({$0.age})  // prints: [21, 17, 20]
let mappedAges = people.map({$0.age})  // prints: [21, 17, 20]  

在这种情况下,映射功能将完成这项工作,无需使用平面映射,因为两者产生相同的结果。此外,在flatMap的这个用例中还有一个无用的包装和展开过程。(closure参数将其返回值包装为可选值,而flatMap的实现在返回可选值之前将其展开)

第二种方法-字符串与收集协议的一致性:
认为需要从人员数组中获取人员姓名列表。您可以使用以下行:

let names = people.flatMap({$0.name})  

如果您使用的是4.0之前的swift版本,您将获得转换后的列表

["Osame", "Masoud", "Mehdi"]  

但是在较新版本中String符合Collection协议,因此,您对平面地图()的使用将匹配第一个重载函数而不是第三个重载函数,并会为您提供转换值的扁平化结果:

["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]

结论:他们不赞成flatMap()的第三个重载,因为这些误用,swift团队决定不赞成flatMap函数的第三个重载。到目前为止,对于您需要处理可选的情况,他们的解决方案是引入一个名为compactMap()的新函数,该函数将为您提供预期的结果。

 类似资料:
  • 本文向大家介绍Android图片压缩(质量压缩和尺寸压缩),包括了Android图片压缩(质量压缩和尺寸压缩)的使用技巧和注意事项,需要的朋友参考一下 在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成

  • 对于我的图像压缩,我使用枕头库获得rgb中的每个像素(例如:(100,0200)。使用哈夫曼编码,我已经将其转换为二进制,以减少比特数。现在,我必须将位序列保存到文本或二进制文件中。压缩文件始终比原始文件小,但目前,我的txt文件比原始文件大。我该怎么办?在那之后,我如何读取文件并解压缩它。以下是说明: 您的代码应该读取图像文件,计算固定长度编码需要多少位,然后应用压缩算法创建较小的编码-您需要实

  • 我一直在计算图像的未压缩和压缩文件大小。这对我来说总是导致压缩图像比我预期的未压缩图像小。如果图像包含大量不同的颜色,则存储调色板会占用大量空间,还需要更多位来存储每个代码。然而,我的问题是,压缩方法是否可能导致比未压缩的RGB图像更大的文件。对于这种压缩方法仍然有用的、总共包含k种不同颜色的最小正方形RGB图像,其大小(像素)是多少?因此,我们想要找到,对于给定的k值,找到最小整数n,对于该整数

  • 如何应用背压来限制生产比并行运行的更多的项目? 为了说明起见,这里有一个快速twitter用户名生成器、一个慢速twitter查找调用、一个慢速twitter文件编写器和一个打印方法。 最终目标是并行运行twitter查找,同时对生成器施加反压力,使其不会发出超出可处理范围的用户名(预计会有一些预取)。 这很好地在一个单独的线程上生成了5个twitter用户名 不确定它是正确的,但我的理由是,从一

  • 问题内容: 我正在通过wifi或移动网络通过网络发送图像,以将其存储在服务器中并再次检索。我已经这样做了,但是由于相机拍摄的图像太大,这使我的应用程序变慢,只是要指出我正在打开图库并从那里拍摄照片,而不是直接从应用程序拍摄照片。我注意到,从相机和图库中获取的来自whatsapp的图像已被压缩到大约50%。100kb。 目前,我的代码获取一个文件,并将其转换为字节,然后发送。这是获取文件并将其转换为

  • 我正在使用Python的Pillow库来读取图像文件。如何使用哈夫曼编码进行压缩和解压缩?以下是说明: 您已经获得了一组示例图像,您的目标是在不丢失任何可感知信息的情况下尽可能压缩它们——解压后,它们应该看起来与原始图像相同。图像本质上存储为一系列颜色点,其中每个点表示为红色、绿色和蓝色(rgb)的组合。rgb值的每个分量范围在0-255之间,因此例如:(100, 0, 200)表示紫色。使用固定