gpt4 book ai didi

clojure - 从嵌套 map (和矢量)创建 HTML 表格

转载 作者:行者123 更新时间:2023-12-04 08:00:27 28 4
gpt4 key购买 nike

我正在尝试创建一个我以前使用 python 编码的表(工作时间表),我认为这对我来说是对 Clojure 语言的一个很好的介绍。

我在 Clojure(或在这方面的 lisp)方面的经验很少,我已经在 google 中完成了我的回合并进行了大量的反复试验,但似乎无法理解这种编码风格。

这是我的示例数据(将来将来自 sqlite 数据库):

(def smpl2 (ref {"Salaried" 
[{"John Doe" ["12:00-20:00" nil nil nil "11:00-19:00"]}
{"Mary Jane" [nil "12:00-20:00" nil nil nil "11:00-19:00"]}]
"Shift Manager"
[{"Peter Simpson" ["12:00-20:00" nil nil nil "11:00-19:00"]}
{"Joe Jones" [nil "12:00-20:00" nil nil nil "11:00-19:00"]}]
"Other"
[{"Super Man" ["07:00-16:00" "07:00-16:00" "07:00-16:00"
"07:00-16:00" "07:00-16:00"]}]}))

我试图通过最初使用 来解决这个问题为 然后转到 剂量最后 map (这似乎更成功)并将内容转储到 html 表中(我的原始 python 程序使用 COM 将它从 sqlite 数据库输出到 excel 电子表格中)。

这是我的尝试(创建表 fn):
(defn html-doc [title & body] 
(html (doctype "xhtml/transitional")
[:html [:head [:title title]] [:body body]]))

(defn create-table []
[:h1 "Schedule"]
[:hr]
[:table (:style "border: 0; width: 90%")
[:th "Name"][:th "Mon"][:th "Tue"][:th "Wed"]
[:th "Thur"][:th "Fri"][:th "Sat"][:th "Sun"]
[:tr
(domap [ct @smpl2]
[:tr [:td (key ct)]
(domap [cl (val ct)]
(domap [c cl]
[:tr [:td (key c)]]))])
]])

(defroutes tstr
(GET "/" ((html-doc "Sample" create-table)))
(ANY "*" 404))

输出带有部分(受薪,经理等)和部分名称的表格,我只是觉得我通过嵌套太多次来滥用 domap,因为我可能需要添加更多 domap 只是为了得到其适当列中的轮类时间和代码变得“肮脏”。

如果我没有提供足够的信息,我提前道歉,我通常不会寻求编码帮助,这也是我的第一个 SO 问题:)。

如果你知道任何更好的方法来做到这一点,甚至是我作为新手应该知道的技巧或窍门,它们绝对是受欢迎的。

谢谢。

最佳答案

没有办法避免某种嵌套循环。但你不需要domap总而言之,Compojure 足够聪明(有时)可以为您扩展序列。 listmapfor足够了。例如 Michał Marczyk 的回答,或:

(defn map-tag [tag xs]
(map (fn [x] [tag x]) xs))

(defn create-table []
(list
[:h1 "Schedule"]
[:hr]
[:table {:style "border: 0; width: 90%"}
[:tr (map-tag :th ["Name" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"])]
[:tr (for [[category people] smpl2]
(list* [:tr [:td category]]
(for [person people
[name hours] person]
[:tr [:td name] (map-tag :td hours)])))]]))

“映射到 seq 并将所有内容包装在同一个标​​签中”模式很常见,有时我喜欢使用辅助函数。

Compojure 扩展一级 seq为你。所以你可以把一些东西扔进 list让标签按顺序出现在你的 HTML 输出中,我这样做是为了让 h1 和 hr 显示出来。在您的代码中,您只是将 h1 和 hr 扔掉了。

但请注意,它只扩展了一层。当您有一个列表列表或一个 seq 列表时,外部 seq 会扩展,但内部 seq 不会。
user> (println (html (list [:div "foo"] (for [x [1 2 3]] [:div x]))))
<div>foo</div>clojure.lang.LazySeq@ea73bbfd

看看内部 seq 如何让 Compojure 变味。调查 compojure.html.gen/expand-seqs看看这是如何工作的,或者如果您愿意,可以更改/修复它。

当您嵌套 for 时,这可能是一个问题。或 forlist , 自 for返回一个惰性序列。但是你只需要避免seq-in-a-seq。我用 list*以上。 list的组合和 html也会工作。还有很多其他的方法。
user> (println (html (list* [:div "foo"] (for [x [1 2 3]] [:div x]))))
<div>foo</div><div>1</div><div>2</div><div>3</div>

user> (println (html (list [:div "foo"] (html (for [x [1 2 3]] [:div x])))))
<div>foo</div><div>1</div><div>2</div><div>3</div>

关于clojure - 从嵌套 map (和矢量)创建 HTML 表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2444170/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com