我需要做这样的事情:
extension Array {
func flat() -> Element { return self.flatMap { $0 } }
}
但是类型推断存在问题:
' flatMap'生成' [SegmentOfResult.Iterator.Element]'而不是 预期的上下文结果类型'元素'
修改:使用示例:
[[1,2],[3,4,5],[6]].flat()
应该生成[1,2,3,4,5,6]
,它与:
[[1,2],[3,4,5],[6]].flatMap { $0 }
答案 0 :(得分:4)
如果你看一下flatMap(_:)
签名,
extension Sequence {
// ...
public func flatMap<SegmentOfResult : Sequence>(_ transform: (Self.Iterator.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element]
// ...
}
你会看到它返回[SegmentOfResult.Iterator.Element]
,其中SegmentOfResult
是从你传递它的函数返回的类型。这不一定与Element
类型相同(因为您的扩展名是所有数组),这就是您的代码无法编译的原因。
为了处理元素为序列的数组,您需要约束扩展名以便Element : Sequence
。
此外,由于您传递给flatMap(_:)
的函数是一个标识转换(它只返回它作为输入接收的元素),您需要将返回类型更改为[Element.Iterator.Element]
(内部元素的数组。)
extension Array where Element : Sequence {
func flat() -> [Element.Iterator.Element] {
return self.flatMap { $0 }
}
}
尽管如此,我认为没有理由不将其作为Sequence
的延伸:
// An extension for a sequence of sequences
extension Sequence where Iterator.Element : Sequence {
// returns an array of the inner element type (an array of the element of the element)
func flat() -> [Iterator.Element.Iterator.Element] {
return self.flatMap { $0 }
}
}
(但是,我并不认为首先需要为此创建扩展名 - array.flatMap{$0}
并不是很长!)