首页 > 解决方案 > 惰性序列 Clojure

问题描述

我试图修改向量的向量,但最终在里面添加了惰性序列。我是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]

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

标签: clojurefunctional-programming

解决方案


在 Clojureformap以及其他处理序列的函数和宏中,生成惰性序列而不是向量。

在 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 ... 1second- 会更容易理解:

(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 函数名称中使用下划线被认为是不好的风格:破折号(如cust-find代替cust_find)更易于阅读和键入。


推荐阅读