@@ -149,7 +149,8 @@ fmapstructure(f, x; kwargs...) = fmap(f, x; walk = (f, x) -> map(f, children(x))
149
149
fcollect(x; exclude = v -> false)
150
150
151
151
Traverse `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.
153
154
154
155
Doesn't recurse inside branches rooted at nodes `v`
155
156
for which `exclude(v) == true`.
@@ -192,11 +193,15 @@ julia> fcollect(m, exclude = v -> Functors.isleaf(v))
192
193
Bar([1, 2, 3])
193
194
```
194
195
"""
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
202
207
end
0 commit comments