Итерация по карте и отображение таблицы

Во-первых, я хочу сказать, что я новичок в clojure, во-вторых, я хочу спросить вас, как перебрать карту и показать все элементы в таблице? Вот что я сделал. Это моя карта-

(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}}))

Я использовал функцию таблицы cldwalker и сделал это...

(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])
                                                     ]] )

результат примерно такой...

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

Как я могу перебрать карту и показать все элементы, а не только один по определенному ключевому слову? Могу ли я каким-то образом увеличить значение ключевого слова и показать его таким образом?


person Shile    schedule 08.11.2013    source источник


Ответы (1)


Карты реализуют интерфейс Seq, что означает, что вы можете использовать все эти полезные функции высшего порядка, такие как map, filter, reduce,... для их обработки. Важной частью здесь является то, что последовательное представление карты состоит из [key value] векторов, например:

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

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

(Если вы не знаете, чем занимаются map и компания, прочтите о них — они вам понравятся (в конце концов)!)

Теперь в вашем случае вас интересуют только значения, а не ключи, похоже, поэтому vals извлечет их для вас:

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

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

Однако ваши значения сами являются картами, и вы хотите получить доступ к определенным ключам в указанных картах и ​​поместить их в один вектор/список. Вы можете сделать это!

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

Это выглядит утомительно. Но создание внутреннего результата — это не что иное, как поиск каждого из списка (!) ключей в хеш-карте, поэтому еще один вариант использования причудливого высшего порядка map:

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

Теперь, на самом деле, Clojure позволяет очень легко применять разные функции (ключевые слова — это функции!) к одному и тому же значению для получения списка результатов — juxt так это называется, беря серию функций и создавая новую, которая делает именно то, что я только что описал.

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

И вот мы переходим к картам:

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

Хорошо, это много для обработки, но вы сможете эффективно работать с Clojure только в том случае, если поймете, какие инструменты он вам предлагает, а функции более высокого уровня, вероятно, будут теми, которые вы будете использовать чаще всего. Наконец, давайте создадим таблицу:

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

А теперь финальная уборка с помощью многопоточных макросов!

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

Да, Clojure может многое, и последовательности + функции высшего порядка — очень мощная комбинация. И еще они решают практические задачи вроде создания таблицы!

person xsc    schedule 08.11.2013
comment
это помогает мне, но я не могу использовать значения из ключа :konacanIshod(:1 :x :2), потому что он содержит карту... как я могу добавить значения из этого ключа? - person Shile; 09.11.2013
comment
comp давайте составим функции. (comp f g) создает функцию, которая сначала применяет g к своим аргументам, а затем f к результату g. Это означает, что (comp :a :b) — это функция, которая выполняет (get-in ... [:b :a]). Короче говоря, используйте (juxt ... (comp :1 :konacanlshod) ...). - person xsc; 09.11.2013
comment
как раз то, что мне было нужно, тнкс. - person Shile; 09.11.2013