Ленивая Последовательность Clojure - PullRequest
0 голосов
/ 26 мая 2018

Я пытался изменить вектор вектора, но в итоге получился 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 голосов
/ 26 мая 2018

В Clojure for и map, а также другие функции и макросы, работающие с последовательностями, генерируют ленивую последовательность вместо вектора.

В 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 считается плохим стилем : тире (как в cust-find вместо * 1031)*) легче читать и легче печатать.

0 голосов
/ 26 мая 2018

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

doall реализует ленивую последовательность.Имейте в виду, что если последовательность огромна, вы, возможно, не захотите этого делать.

...