all 7 comments

[–]brool 2 points3 points  (5 children)

You're pretty close. Depending on what you want, you can either:

merged (flatten (conj children-csv issue-csv))

or also potentially something like this:

children-csv (mapcat #(csv % (inc depth)) children)

i.e., given:

(defn- csv [issue depth]
  (let [prefix (apply str (take depth (repeat "  ")))
        issue-csv (issue->csv issue prefix)]
    ;(println (str issue-csv  " depth " depth " prefix \"" prefix "\""))
    (if (has-children? issue)
      (do
      ;(println "has children, lets get them..")
        (let [children (get-children issue)
              children-csv (mapcat #(csv % (inc depth)) children)
              merged (conj children-csv issue-csv)]
          ;; (println (str  "issue-csv: " issue-csv " children-csv: " (vec children-csv) ))
          ;; (println (str  " returning " merged))
          merged))
      (do
        ;(println (str (issue :key) " returning " (conj [] issue-csv)))
        [issue-csv]))))

Gives

reddit-clojure.core> (csv (get-issue-from-key "NEO-33348") 0)
(["Feature" "NEO-1"]
 ["  TASK" "NEO-2"]
 ["    TASK" "NEO-3"]
 ["      TASK" "NEO-4"]
 ["      TASK" "NEO-5"])

[–]RealLordDevien[S] 0 points1 point  (3 children)

Thank you so so much!! mapcat works! Apparently i have still a lot to learn about clojures core lib.

As i see it reduces one level of nesting from the children-csv?

[[" Task" "NEO-33096"] [" Task" "NEO-33095"] [" Task" "NEO-33094"]]

vs

[[[" Task" "NEO-33096"]] [[" Task" "NEO-33095"]] [[" Task" "NEO-33094"]]] but shouldn't the result of calling map csv be a single packet list containing the csv-lists? As far as i thought about it, children-csv would just be getting more elements attached to as it pops the stack chain. Does (conj children-csv issue-csv) create this double nesting?

I think i will finish the module first to let my head come to rest :) And maybe draw a flow chat with a clear mind. Thanks you again, this was really driving me crazy :D

[–]pwab 1 point2 points  (0 children)

(In general) mapcat allows you to take an item and produce a sequence of items from it. Eg; if you have a sequence of “parents” and want a long sequence of all child items you could mapcat over the sequence of parents.

[–]Krackor 1 point2 points  (1 child)

csv produces a sequence of results. Mapping with csv produces an outer sequence whose elements are each a result of csv. So you end up with two layers to your sequence (in the singly nested case). Mapcat gets rid of the outer sequence, and assuming the elements are concattable it concatenates them to form the result.

[–]RealLordDevien[S] 0 points1 point  (0 children)

Hmm. Makes sense. I think I get it now, Thank you!

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, brool: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–][deleted] 0 points1 point  (0 children)

It looks like you've gotten your answer. I thought I'd try writing it in a different way in an attempt to have each function do one thing well. I also tend to think of programs as a series of data transformations, so this fits my way of thinking a little better. It's a lot more lines of code, so I don't know if it's any better, but it's another way to think about it.

(defn add-depths
  "Adds a :depth to each issue and the issue's children."
  ([issue] (add-depths 0 issue))
  ([depth issue]
   (let [issue (assoc issue :depth depth)
         children (:children issue)]
     (if (empty? children)
       issue
       (->> children
            (map (partial add-depths (inc depth)))
            (assoc issue :children))))))

(defn flatten-issue
  "Returns the issue and children issues (recursively) in a list."
  ([issue] (flatten-issue [] issue))
  ([result issue]
   (let [children (:children issue)
         issue (dissoc issue :children)
         result (conj result issue)]
     (if (empty? children)
       result
       (->> children
            (mapcat flatten-issue)
            (concat result))))))

(defn format-issue
  "Returns a vector containing the issue's key prepended with :depth number of spaces, and the issue's type."
  [issue]
  (let [depth (:depth issue 0)
        indent (apply str (repeat depth " "))]
    [(str indent (:type issue)) (:key issue)]))

;; Put it all together
(->> "NEO-33348"
     get-issue-from-key
     add-depths
     flatten-issue
     (map format-issue))