The new flatten
function is an odd creature. You’d think it would work like flatMap and it kind of sort of does but not entirely.
Here’s a quick example:
let array = [[1], [2, 3, 4], [5], [6, 7]]
print(array.flatMap({$0}))
// [1, 2, 3, 4, 5, 6, 7]
print(array.flatten())
// FlattenBidirectionalCollection<Array<Array<Int>>>(_base: [[1], [2, 3, 4], [5], [6, 7]])
print(Array(array.flatten()))
// [1, 2, 3, 4, 5, 6, 7]
The flatten
function returns a new seemingly lazy collection. I’m guessing it’s fairly similar to:
print(array.lazy.flatMap({$0}))
// Swift.LazyMapCollection<Swift.Array<Swift.Array<Swift.Int>>, Swift.Array<Swift.Int>>(_base: [[1], [2, 3, 4], [5], [6, 7]], _transform: (Function))))
And like most collection / sequences, you can iterate over the results or force them to an array, etc.
There are actually 6 different versions of flatten in beta 6, which seem to start with collections of collections and build from there. The fourth of these is a real doozy.
extension CollectionType where Generator.Element : CollectionType
extension CollectionType where Generator.Element : CollectionType, Index : BidirectionalIndexType, Generator.Element.Index : BidirectionalIndexType
extension LazyCollectionType where Generator.Element : CollectionType, Elements.Generator.Element : CollectionType, Generator.Element == Elements.Generator.Element
extension LazyCollectionType where Generator.Element : CollectionType, Index : BidirectionalIndexType, Generator.Element.Index : BidirectionalIndexType, Elements.Generator.Element : CollectionType, Elements.Index : BidirectionalIndexType, Elements.Generator.Element.Index : BidirectionalIndexType, Generator.Element == Elements.Generator.Element
extension LazySequenceType where Elements.Generator.Element == Generator.Element, Generator.Element : SequenceType
extension SequenceType where Generator.Element : SequenceType
More complex items can be called with flatten()
but don’t necessarily return the thing you might expect:
let complexerArray = [[[1]], [[2]], [[3]], [[4, 5]]]
print(Array(complexerArray.flatten()))
// [[1], [2], [3], [4, 5]]
You can chain .flatten().flatten()
to get [1, 2, 3, 4, 5] in this example but you can’t apply the function to an already flat collection.
I’m sure there’s a deeply compelling reason to prefer flatten over flatMap for simple flattening (it’s certainly easier to incorporate with a function call vs a closure) but I’m a little baffled as to why it’s popped up in the standard library, especially with such bizarre and tortured declarations.
The big win of today’s exercise seems to be standardizing on some greppage:
grep func $0 | sed "s/^ *//" | sed "s/.*func //" | grep -v "///" | sort | uniq | open -f
which you can then diff -y, and search for < and >. Today’s keywords appear to be advance, distance, extend, splice
on the Beta 5 side (advancedBy
and distanceTo
are the renamed versions) and appendContentsOf, flatten
, and insertContentsOf
on Beta 6.