当前位置: 首页 > 面试题库 >

Swift中flatMap和compactMap之间的区别

公西宏毅
2023-03-14
问题内容

Swift 4.1中 似乎flatMap已弃用。但是在 Swift 4.1中
有一个新方法compactMap正在做同样的事情?有了它,flatMap您可以变换集合中的每个对象,然后删除所有为零的项目。
像flatMap一样

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 在做同样的事情。

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


问题答案:

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

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

可以通过两种方式滥用最后一个重载函数:
考虑以下struct和array:

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")]

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

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

在这种情况下,该map功能将完成工作,并且无需使用flatMap,因为两者都会产生相同的结果。此外,在flatMap的这种用例内部有一个无用的包装和解包过程(闭包参数使用Optional包装其返回的值,flatMap的实现在返回Optional之前将其解包装)

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

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

如果您使用的是4.0之前的快速版本,则将获得以下内容的转换列表:

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

但在较新的版本中String符合Collection协议,因此,您对的使用flatMap()将匹配第一个重载函数,而不是第三个重载函数,并且将为您带来转换后的值的平坦结果:

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

结论:他们弃用了flatMap()的第三重载。
由于这些误用,迅速团队决定将第三重载弃用到flatMap函数。Optional到目前为止,他们针对需要处理s
的情况的解决方案是引入一个名为的新函数compactMap(),它将为您带来预期的结果。



 类似资料:
  • 有人能描述一下flatMap与compactMap的这种行为吗?compactMap不是刚刚重命名为flatMap吗?因为我发现他们表现不同 这是它打印的 有人能告诉我为什么当我使用嵌套数组不扁平吗?

  • 有人能给我解释一下map和flatMap之间的区别,以及什么是各自的好用例吗? “结果扁平化”是什么意思?它有什么好处?

  • 问题内容: 考虑此函数,该函数采用通用参数,并根据谓词过滤数组。这与Swift提供的功能相同。 这有什么不同 即使在后面的示例中,我们也无法达到泛型的意义吗? 问题答案: 泛型是类型安全的,这意味着如果您将字符串作为泛型传递并尝试将其用作整数,则编译器会抱怨并且您将无法编译您的(很好)。(发生这种情况是因为Swift使用的是 Static类型 ,并且能够给您一个 编译器 错误 ) 如果使用AnyO

  • 问题内容: 在Java 8中,和方法之间有什么区别? 问题答案: 双方map并可以应用到他们都回报。不同之处在于,该map运算为每个输入值生成一个输出值,而该运算为每个输入值生成任意数量(零个或多个)的值。 这反映在每个操作的参数中。 该map操作采用一个,对输入流中的每个值调用,并产生一个结果值,该结果值发送到输出流。 该操作采用的功能在概念上要消耗一个值并产生任意数量的值。但是,在Java中,

  • 我有一个struct类型的对象数组 现在我想要一个数组,其中每个对象数组的所有元素组成如下所示: 结果: 紧凑型:[[1,2][1,2][1,2][1,2]]扁平:[1,2,1,2,1,2] 由于平面图在Swift 4.1中已弃用,我尝试使用compactMap,但它给出了数组数组而不是单个数组。 如何通过compactMap实现,就像我通过flatMap实现一样。

  • 问题内容: 在教程中,他们写到在功能上是相同的,即使闭包比阻塞更容易,并且避免了块和内存管理的复杂性,我看过很多教程,但是除了这些,我没有理解swift的“ closure”和Objective-C“块”。 问题答案: 摘录自:Apple Inc.“将Swift与Cocoa和Objective-C结合使用。” iBooks: “ Swift闭包和Objective-C块是兼容的,因此您可以将Swi