@@ -149,7 +149,8 @@ fmapstructure(f, x; kwargs...) = fmap(f, x; walk = (f, x) -> map(f, children(x))
149149 fcollect(x; exclude = v -> false)
150150
151151Traverse `x` by recursing each child of `x` as defined by [`functor`](@ref)
152- and collecting the results into a flat array.
152+ and collecting the results into a flat array, ordered by a breadth-first
153+ traversal of `x`, respecting the iteration order of `children` calls.
153154
154155Doesn't recurse inside branches rooted at nodes `v`
155156for which `exclude(v) == true`.
@@ -192,11 +193,15 @@ julia> fcollect(m, exclude = v -> Functors.isleaf(v))
192193 Bar([1, 2, 3])
193194```
194195"""
195- function fcollect (x; cache = [], exclude = v -> false )
196- x in cache && return cache
197- if ! exclude (x)
198- push! (cache, x)
199- foreach (y -> fcollect (y; cache = cache, exclude = exclude), children (x))
200- end
201- return cache
196+ function fcollect (x; output = [], cache = Base. IdSet (), exclude = v -> false )
197+ # note: we don't have an `OrderedIdSet`, so we use an `IdSet` for the cache
198+ # (to ensure we get exactly 1 copy of each distinct array), and a usual `Vector`
199+ # for the results, to preserve traversal order (important downstream!).
200+ x in cache && return output
201+ if ! exclude (x)
202+ push! (cache, x)
203+ push! (output, x)
204+ foreach (y -> fcollect (y; cache= cache, output= output, exclude= exclude), children (x))
205+ end
206+ return output
202207end
0 commit comments