iCo*_*ime 2 lisp functional-programming vector clojure
我有一个对象矢量,我想将其转换为对象矢量的矢量,其中子矢量中的每个对象对于特定成员具有相同的值.例如
[{:sku "105"}, {:sku "105"}, {:sku "120"}]
Run Code Online (Sandbox Code Playgroud)
变
[[{:sku "105"}, {:sku "105"}], [{:sku "120"}]]
Run Code Online (Sandbox Code Playgroud)
我正在努力掌握功能的思维方式,但我很确定我还没有,因为我的代码看起来很笨拙.但这是我到目前为止所拥有的:
(defn separate-by-invoice [original-invoices]
(let [sorted-invoices (sort-by :invoice-number original-invoices)]
(def temp-invoices [])
(reduce (fn [final-invoices invoice]
(let [prev-invoice-number (get-in (last temp-invoices) [:invoice-number])
invoice-number (get-in invoice [:invoice-number])]
(if (= prev-invoice-number invoice-number)
(do
(into temp-invoices invoice))
(do
(into final-invoices temp-invoices)
(def temp-invoices [])
(into temp-invoices invoice))))
final-invoices)
[]
sorted-invoices)))
Run Code Online (Sandbox Code Playgroud)
基本上,我的想法是,我形成一个向量,临时发票,并用所有具有相同发票号的条目填充它,然后一旦我们获得所有这些条目,将该向量插入到final-vector中,然后返回那个价值.但相反,似乎最终发票总是一个空的载体.我究竟做错了什么?这通常是如何在clojure中完成的?
让我们把它分成两个子问题:
user> (def x [{:sku "105"}, {:sku "105"}, {:sku "120"}])
#<Var@18bc9d90: [{:sku "105"} {:sku "105"} {:sku "120"}]>
Run Code Online (Sandbox Code Playgroud)
首先将类似数据组合在一起:
user> (sort-by :sku x)
({:sku "105"} {:sku "105"} {:sku "120"})
Run Code Online (Sandbox Code Playgroud)
然后在每次更改时拆分:
user> (partition-by :sku (sort-by :sku x))
(({:sku "105"} {:sku "105"}) ({:sku "120"}))
Run Code Online (Sandbox Code Playgroud)
也可以使用线程样式编写,以使流程更易于阅读:
user> (->> x
(sort-by :sku)
(partition-by :sku)
(mapv vec))
[[{:sku "105"} {:sku "105"}] [{:sku "120"}]]
Run Code Online (Sandbox Code Playgroud)