2014-02-24 23 views
0

我有什么:构建表序列的序列

  • 集(地图在这种情况下,Seqable更普遍),我想在降价表(whichever flavour of Markdown reddit uses)来显示项目。
  • 访问器函数的序列,它们在映射到集合上时生成所需表的每列的内容。
  • 序列的列映射:(for [x accessors] (map x coll))

我想要做的事:

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

我似乎无法得到第一步的工作。我所有的尝试似乎都追加了\ n本身的无限序列,而不是将序列作为一个序列或类似问题中的单个对象。一点帮助?

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

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

编辑您的样品后:

(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

我试图实现的有用但不是完全交错 - 我想要每个映射的第一个元素依次,然后是\ n,然后是第二个元素,依此类推。可能是我没有给出像edbond这样的例子说的错。 – Magos

+0

哦,这很整齐。从来没有真正有原因使用'juxt',但这是一个巧妙的应用程序。之后仍然需要“扁平化”,但它得到正确的顺序。 – Magos

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

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

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是开源的,因此您也可以根据需要修改副本以达到您的目的。 –