2014-02-24 2 views
0

Что у меня есть:Построение таблицы с последовательностью последовательностей

  • Collection (карта в этом случае, Seqable в более общем плане) элементов, которые я хочу, чтобы отобразить в таблице Markdown (whichever flavour of Markdown reddit uses).
  • Последовательность функций доступа, которые создают содержимое каждого столбца нужной таблицы при сопоставлении с коллекцией.
  • Последовательность этих отображений столбцов: (for [x accessors] (map x coll))

То, что я пытаюсь сделать:

  • Append (repeat "\n") последовательности отображений, в качестве разделителя элементов.
  • apply interleave над последовательностью последовательностей.
  • Использовать полученную последовательность с помощью clojure.string/join для вставки разделителя ячейки таблицы "" " и склеить все это вместе.

Я просто не могу сделать первый шаг. Все мои попытки, похоже, добавляют бесконечную последовательность самого \ n, а не эту последовательность, как отдельный объект в seq seqs или подобных проблемах. Небольшая помощь?

Редактировать: Небольшой пример ввода/вывода имеет смысл для чего-то подобного, поэтому я должен добавить его. Для простоты мы просто перечислим числа и функции из них. Вход:

(markdown-table [[[identity] "Number"] 
       [[(partial * 2)] "Doubled"]] (range 6)) 

(Строки и такие для создания имен столбцов - может изменить эту установку позже, но вы можете увидеть функции аксессоры там просто листинг самого и его удвоение числа..)
Для этого я есть последовательность ((0 1 2 3 4 5) (0 2 4 6 8 10)) и хотите, чтобы в конечном итоге с последовательностью

(0 0 "\n" 1 2 "\n" 2 4 "\n" 3 6 "\n" 4 8 "\n" 5 10 "\n") 
+0

шоу вход и желаемый результат, по крайней мере, код, если у вас есть – edbond

ответ

0

Вы ищете interpose

(def items [1 2 3 4 5]) 

(def accesors [(fn [x] (inc x)) 
       (fn [x] (- 10 x))]) 

(def mappings (for [x accesors] 
       (map x items))) 
=> ((2 3 4 5 6) (9 8 7 6 5)) 


(interpose "\n" mappings) 
=> ((2 3 4 5 6) "\n" (9 8 7 6 5)) 

Edit после образца:

(map (fn [& args] 
     (apply (juxt identity (partial * 2)) args)) 
     (range 6)) 
=> ([0 0] [1 2] [2 4] [3 6] [4 8] [5 10]) 

Тогда просто использовать вставляю на нем.

(def accessors [(fn [x] (identity x)) 
       (fn [x] (* x 2))]) 

(def mappings (map (fn [& args] 
        (apply (apply juxt accessors) args)) 
        (range 6))) 

(interpose "\n" mappings) 
=> ([0 0] "\n" [1 2] "\n" [2 4] "\n" [3 6] "\n" [4 8] "\n" [5 10]) 
+0

Полезный, но не совсем чередование, которое я пытаюсь достичь - я бы хотел, чтобы первый элемент каждого сопоставления упорядочивался, затем a \ n, затем второй элемент и так далее. Вероятно, моя вина за то, что я не привела пример, подобный edbond. – Magos

+0

О, это просто. Никогда не было причин использовать 'juxt' раньше, но это его аккуратное применение. По-прежнему нужно «сплющивать», но он получает правильный порядок. – Magos

0

Во время ответа я, кажется, нашел способ, который работает с использованием моего первоначального подхода. Поместив последовательности отображения в вектор, я могу добавить последовательность \ n как одно значение для чередования, а не как бесконечное число значений, как с concat, cons и так далее. Полученный код был

(defn- markdown-table 
    "Create Markdown for a table displaying a collection 
    Columns defines the columns to show - give pairs of accessor sequence and display names." 
    [columns coll] 
    (let[columns-def (str "|" (clojure.string/join "|" (concat (map second columns) 
                  "\n" 
                  ;;All columns are center aligned, for now. 
                  (map (constantly ":--:") columns))) 
         "\n") 
     accessors (for [[x _] columns] (apply comp (reverse x))) ;;Reverse so composition is leftmost-first 
     columns (for [x accessors] (map x coll)) 
     item-separated (conj (vec columns) (repeat "\n")) 
     cells (apply interleave item-separated) 
     ](clojure.string/join "|" (cons columns-def cells)))) 

Еще не совсем уверен в том, как она обрабатывает определения столбцов, но это, кажется, дает правильный вывод.

2

Clojure уже есть что-то похожее на то, что вы пытаетесь сделать

(defn markdown-table 
    [specs xs] 
    (clojure.pprint/print-table 
    (for [x xs] 
     (into {} 
     (for [{:keys [label fn]} specs] [label (fn x)]))))) 

(markdown-table [{:label "Number", :fn identity} 
       {:label "Doubled", :fn (partial * 2)}] 
       (range 6)) 

выход (может обернуть в with-out-str):

 
| Number | Doubled | 
|--------+---------| 
|  0 |  0 | 
|  1 |  2 | 
|  2 |  4 | 
|  3 |  6 | 
|  4 |  8 | 
|  5 |  10 | 
+0

Не знал об этом. Получается довольно близко, хотя верхняя часть, которая показывает столбцы, не работает с Markdown, и мне придется вернуться к ней для исправления. Тем не менее, спасибо, что указали это. – Magos

+0

@ user1571406 Вы ставите. Как и в случае с остальной частью Clojure, clojure.pprint является открытым исходным кодом, поэтому вы также можете изменить копию по своему желанию. –

Смежные вопросы