基于关键字将矢量拆分为矢量矢量

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中完成的?

Art*_*ldt 5

让我们把它分成两个子问题:

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)