构建一个包含序列序列的表

时间:2014-02-24 15:18:55

标签: clojure

我有什么:

  • 我希望在Markdown表(whichever flavour of Markdown reddit uses)中显示的项目的集合(在此实例中为地图,更一般地为Seqable)。
  • 访问者函数的序列,在映射到集合时生成所需表的每列的内容。
  • 这些列映射的顺序:(for [x accessors] (map x coll))

我正在尝试做什么:

  • (repeat "\n")附加到映射序列,作为项目分隔符。
  • apply interleave超过序列序列。
  • 使用clojure.string/join使用结果序列来插入'表格单元格分隔符'“|”并将它们粘在一起。

我似乎无法迈出第一步。我所有的尝试似乎都附加了\ n本身的无限序列而不是序列作为seqs或类似问题的seq中的单个对象。一点帮助?

编辑:一个小的输入/输出示例对这样的事情有意义,所以我最好添加它。为简单起见,我们只列出它们的数字和功能。输入:

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

3 个答案:

答案 0 :(得分: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 |

答案 1 :(得分: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))
您的样本后

编辑

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

答案 2 :(得分:0)

在回复时,我似乎找到了一种方法,可以使用我原来的方法。通过将映射序列放在向量中,我可以将\ n序列作为一个值附加到交错而不是与concatcons等无限多个值。结果代码是

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

仍然不太确定它处理列定义的方式,但它似乎给出了正确的输出。