懒惰序列Clojure

时间:2018-05-26 02:36:08

标签: clojure functional-programming

我试图修改向量的向量,但结果是内部的lazy-seq。我是clojure的新手。有人可以帮我正确地解决这个问题吗?

(require '[clojure.string :as str])

;;READ CUST.TXT
(def my_str(slurp "cust.txt"))
(defn esplit [x] (str/split x #"\|" ))
(def cust (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
;;func to print
(for [i cust] (do (println (str (subs (str i) 2 3) ": [" (subs (str i) 5 (count (str i)))))))


;;CODE TO SEARCH CUST
(defn cust_find [x] (for [i cust :when (= (first i) x )] (do (nth i 1))))
(type (cust_find "2"))

;;READ PROD.TXT
(def my_str(slurp "prod.txt"))
(def prod (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
;;func to print
(for [i prod] (do (println (str (subs (str i) 2 3) ": [" (subs (str i) 5 (count (str i)))))))

;;CODE TO SEARCH PROD
(defn prod_find [x y] (for [i prod :when (= (first i) x )] (nth i y)))
(prod_find "2" 1)

(def my_str(slurp "sales.txt"))
(def sales (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
; (for [i (range(count sales))] (cust_find (nth (nth sales i) 1)))
; (defn fill_sales_1 [x]
;   (assoc x 1
;     (cust_find (nth x 1))))
; (def sales(map fill_sales_1 (sales)))
(def sales (vec (for [i (range(count sales))]  (assoc (nth sales i) 1 (str (cust_find (nth (nth sales i) 1)))))))
; (for [i (range(count sales))] (assoc (nth sales i) 2 (str (prod_find (nth (nth sales i) 2) 1))))
(for [i sales] (println i))

当我打印销售媒介时,我得到了

[1 clojure.lang.LazySeq@10ae5ccd 1 3]
[2 clojure.lang.LazySeq@a5d0ddf9 2 3]
[3 clojure.lang.LazySeq@a5d0ddf9 1 1]
[4 clojure.lang.LazySeq@d80cb028 3 4]

如果您需要文本文件,我也会上传它们。

2 个答案:

答案 0 :(得分:0)

在Clojure中,formap,以及使用序列的其他函数和宏,生成一个惰性序列而不是向量。

在REPL中,懒人序列通常在打印时完全计算 - 要打印它,它足以删除倒数第二行中的str

(def sales (vec (for [i (range(count sales))]  (assoc (nth sales i) 1 (cust_find (nth (nth sales i) 1))))))

为了以防万一,请注意您的代码可以被美化/简化以更好地传达意义。例如,您只是迭代sales的序列 - 您不需要迭代索引,然后使用nth获取每个项目:

(def sales
  (vec (for [rec sales])
         (assoc rec 1 (cust_find (nth rec 1)))))

其次,您可以将nth ... 1替换为second - 这将更容易理解:

(def sales
  (vec (for [rec sales])
         (assoc rec 1 (cust_find (second rec))))

或者,您也可以使用update代替assoc

(def sales
  (vec (for [rec sales])
         (update rec 1 cust_find)))

而且,你真的需要这里的外vec吗?没有它,你可以完成你想要的大部分工作:

(def sales
  (for [rec sales])
    (update rec 1 cust_find))

此外,在Clojure函数名称中使用下划线被视为bad style:破折号(如cust-find而非cust_find)更易于阅读且更易于输入。

答案 1 :(得分:-1)

(for [i sales] (println (doall i)))

doall实现了一个懒惰的序列。请记住,如果序列很大,你可能不想这样做。