Shile
Shile

Reputation: 1063

Iterating through map and showing table

The first thing I want to say is that I am new to clojure, secondly I want to ask you how to iterate through a map and show all elements in a table? Here is what I have done. This is my map-

(def kvote(assoc kvote (keyword kljuc){:id id :liga liga :dan dan :cas cas :domaciTim    domaciTim :gostujuciTim gostujuciTim :par par :konacanIshod{:1 jedinica :x nerijeseno :2 dvojka}}))

I was using cldwalker table function and did this...

(table [ ["liga" "dan" "cas" "id" "par" "1" "X" "2"] [(:liga(get kvote(keyword :101)))
                                                     (:dan(get kvote(keyword :101)))
                                                      (:cas(get kvote(keyword :101)))
                                                    (:id(get kvote(keyword :101))) 
                                                    (:par(get kvote(keyword :101)))
                                                      (get-in kvote [:101 :konacanIshod :1])
                                                      (get-in kvote [:101 :konacanIshod :x])
                                                      (get-in kvote [:101 :konacanIshod :2])
                                                     ]] )

the result is something like this...

+---------+---------+-------+-----+--------------------+-----+-----+---+
| liga    | dan     | cas   | id  | par                | 1   | X   | 2 |
+---------+---------+-------+-----+--------------------+-----+-----+---+
| Serie A | nedelja | 20:00 | 101 | Bologna - Cagliari | 1.5 | 2.3 | 4 |
+---------+---------+-------+-----+--------------------+-----+-----+---+

How can I iterate through the map and show all the elements, not only one by the specific keyword? Can I somehow increment my keyword value and show it like that?

Upvotes: 0

Views: 174

Answers (1)

xsc
xsc

Reputation: 6073

Maps implement the Seq interface, meaning you can use all these useful higher-order functions like map, filter, reduce, ... to process them. The important part here is that the sequential representation of a map consists of [key value] vectors, e.g.:

(seq {:a 0 :b 1})
;; => ([:a 0] [:b 1])

(map (fn [x] (inc (second x))) {:a 0 :b 1})
;; => (1 2)

(If you do not know what map & co. do, read up on them - you will love them (eventually)!)

Now, in your case you're only interested in the values, not the keys, it seems, so vals will retrieve them for you:

(vals {:a 0 :b 1})
;; => (0 1)

(map inc (vals {:a 0 :b 1}))
;; => (1 2)

Your values, however, are maps themselves and you want to access certain keys in said maps and put them into a single vector/list. You can do that!

(map
  (fn [x]
    [(:key-1 x) (:key-2 x) ...])
  (vals your-map-of-maps))

This looks tedious. But creating the inner result is nothing else then looking up each one of a list (!) of keys in a hash map, so another use case for fancy higher-order map:

(map 
  (fn [x]
    (map (fn [k] (k x)) [:key-1 :key-2 ...]))
  (vals your-map-of-maps))

Now, actually Clojure makes it really easy to apply different functions (keywords are functions!) to the same value to obtain a list of results - juxt is what it's called, taking a series of functions and producing a new one that does exactly what I just described.

(def inc-and-dec (juxt inc dec))
(inc-and-dec 1)
;; => [2 0]

And here we go for maps:

((juxt :a :b) {:a 0 :b 1 :c 2})
;; => [0 1]

Okay, that's a lot to process but you'll only be able to work efficiently with Clojure if you understand what tools it offers you - and higher-level functions are probably those you'll use the most. Finally, let us create a table:

(table
  (cons
    ["header-1" "header-2" ...]
    (map (juxt :key-1 :key-2 ...) (vals your-map-of-maps))))

And now for the grand finale, cleaning up using threading macros!

(->> your-map-of-maps
     (map (juxt :key-1 :key-2 ...))
     (cons ["header-1" "header-2" ...])
     (table))

Yup, there's a lot Clojure can do, and sequences + higher-order-functions are a very powerful combination. And they still solve practical problems like creating a table!

Upvotes: 3

Related Questions