2014-11-02 26 views
1

我有这样过滤Clojure中

(def invoice 
{:productId ["001" "002" "003" "004" "005" "006" "007" "008" "009" "010"], 
:price ["50" "60" "70" "50" "40" "45" "55" "90" "50" "70"], 
:quantity ["0" "0" "1" "2" "0" "0" "0" "0" "0" "1"]}) 

地图如何过滤所以它只能说明产品id其中数量为1个或更多?

我已经尝试过做这样

(filter (> (invoice :quantity %) 1) (map list (invoice :price) (invoice :quantity) (invoice :productid)) 

,但它不工作

回答

1

第一步是构造一对产品ID和数量:

(map vector (invoice :quantity) (invoice :productId)) 
;; ["0" "001"] .... first element would be quantity and second is productiID 

第二步将过滤出哪个数量大于0,这里我使用(Integer。xx)将数量转换为数字。

(filter #(> (Integer. (first %)) 0) (map vector (invoice :quantity) (invoice :productId))) 
2

您需要创建一个函数来传递的第一个参数filter。其次,需要在做你可以不使用read-string比较为1,前解析量:

(filter #(> (read-string (second %)) 1) (map list (invoice :price) (invoice :quantity) (invoice :productId))) 
+0

地图调用可能是'(地图列表((juxt:price:quantity:productId)invoce))' – noisesmith 2014-11-02 18:33:42

+0

@noisesmith ITYM'(应用地图列表((juxt ...)...))''。 – amalloy 2014-11-04 05:20:27

0

通常情况下,数据是比较容易处理时,它的一点点更“正常”的,所以你不必担心像你的样品中的索引。我建议将它存储为({:id x:price y:quant z} ...)的一个seq。

这个函数是:

(defn invoices [invoice] 
    (map (fn [id price quant] 
      {:id id 
      :price price 
      :quant quant}) (:prouctId invoice) 
          (:price invoice) 
          (:quantity invoice)) 
从那里

然后,你可以简单地

(->> invoice 
    invoices 
    (remove #(= "0" (:price %)) ;; remove "0" prices 
    (map :id))) ;; get ids 

假设你的数据集不具有否定的数量。