我希望allMembers
属于[Member]
类型。但它的类型是[[Member]]
。为什么compactMap
不会返回[Member]
类型的结果?
class Team {
let members = Array(repeating: Member(), count: 2)
}
class Member {
}
let teams = Array(repeating: Team(), count: 3)
let allMembers = teams.compactMap { $0.members }
答案 0 :(得分:3)
您实际需要flatMap
,而不是compactMap
。
尽管之前(在Swift 4.1之前),compactMap
也称为flatMap
,但它具有与当前flatMap
不同的实现和函数签名,因为compactMap
可以使用map
和filter
调用map
每个元素到新元素,而只保留non-nil
个元素。另一方面,flatMap
在映射元素时展平嵌套列表。
This是flatMap
上仍然存在的Sequence
,this是flatMap
上已弃用的Sequence
,已重命名为compactMap
1}}。如您所见,重命名版本的函数签名是
func flatMap<ElementOfResult>(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
,所以它的闭包输入参数返回Optional
值(就像compactMap
现在一样),而现有的flatMap
有一个函数签名
func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
,在其闭包中不返回Optional
。
您应该使用未弃用的flatMap
来展平您的嵌套Array<Array<Member>>
。
let allMembers = teams.flatMap { $0.members }
答案 1 :(得分:0)
在@ David的回答中添加一些细节:
在序列(如数组)上使用flatMap,过滤任何映射到nil的内容现已弃用,并替换为compactMap。
在带有闭包的序列上使用flatMap,该闭包返回一个可选的。
Sequence.flatMap<U>(_ transform: (Element) -> U?) -> U?
例如:
而不是:
let names: [String?] = ["Tom", nil, "Peter", nil, "Harry"]
let valid = names.flatMap { $0 }
你必须使用:
let valid = names.compactMap { $0 }
// ["Tom", "Peter", "Harry"]
let names: [String?] = ["Tom", nil, "Peter", nil, "Harry"]
let counts = names.compactMap { $0?.count }
// [3, 5, 5]
但同样,Swift 4.1并没有弃用flatMap的所有用途 - 在3个案例中,只有一个案例正在发生变化。以下两种情况就是您需要使用flatMap的地方:
1)在具有返回序列的闭包的序列上使用flatMap:
Sequence.flatMap<S>(_ transform: (Element) -> S) -> [S.Element] where S : Sequence
示例:
let scores = [[5,2,7], [4,8], [9,1,3]]
let allScores = scores.flatMap { $0 }
// [5, 2, 7, 4, 8, 9, 1, 3]
let passMarks = scores.flatMap { $0.filter { $0 > 5} }
// [7, 8, 9]
2)在可选项上使用flatMap:闭包采用optional的非nil值并返回一个可选项。如果原始可选项为nil,则flatMap返回nil:
Optional.flatMap<U>(_ transform: (Wrapped) -> U?) -> U?
示例:
let input: Int? = Int("8")
let passMark: Int? = input.flatMap { $0 > 5 ? $0 : nil}
// Optional(8)
有关详细信息,请参阅here