This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-08-22
Channels
- # admin-announcements (8)
- # beginners (23)
- # boot (121)
- # cider (4)
- # clojure (19)
- # clojure-bangladesh (14)
- # clojure-berlin (3)
- # clojure-brasil (2)
- # clojure-dev (5)
- # clojure-russia (13)
- # clojure-sweden (1)
- # clojurescript (99)
- # clojutre (3)
- # datascript (2)
- # funcool (1)
- # jobs (1)
- # om (23)
- # overtone (1)
- # reagent (10)
- # spacemacs (3)
Could someone explain how this implementation of flatten using mapcat works? (looking at answers from 4clojure)
(fn flatten* [x]
(if (coll? x)
(mapcat flatten* x)
[x]))
ooh, I think I may get it now (after some thinking). Does it just recur on each element in x, putting it into its own vector if it’s not a collection, and then concatenate all of those single element vectors?
I was drawing same conclusion. So it walks down tree of nested collections creating single vectors for the contents I think?
At every node if it's a collection (a branch) it applies itself recursively and concatenates the results. If it's not a collection (a leaf), it's made into a collection so that the parent branch will be able to apply flatten* to it.
I think you both have the right idea, but in my own words, you have a function that returns a flattened list of the elements you gave it. When the “elements you gave it” is a single item, then a flattened list is obviously [element]
. If the element is a collection, you need to concatenate the flattened lists of the elements in the collection.
Which is clever, however it's also recursive which means the depth of the tree has to fit on the stack
So not very big trees would give you a stackoverflow
As opposed to the something that walked the tree in order and accumulated the flattened result
thanks a ton for that very clear explanation @alexmiller
I just did a quick search to read up more on mapcat and how it differs from the accumulated alternative you mention, and I found this: http://clojurian.blogspot.sg/2012/11/beware-of-mapcat.html which provides a different version of mapcat that purports to use less memory 😃
A new screencast: https://www.youtube.com/watch?v=mi3OtBc73-k
Only if you wrap it in an anon fn
But there is .. For chained interop
hmm trying to find a way to use filter with a java interop predicate in a thread-first macro
that's how you do it
there's also memfn although I can't say I ever see people use it https://clojuredocs.org/clojure.core/memfn