我想的Clojure我試圖找出如何實現以下算法,Clojure的While循環
我從我想繼續讀書,直到它不是一個分隔符的輸入流中讀取。
我可以在java中用while循環做到這一點,但我似乎無法弄清楚如何在clojure中做到這一點?
while read readChar != delimiter do some processing.... end while
我想的Clojure我試圖找出如何實現以下算法,Clojure的While循環
我從我想繼續讀書,直到它不是一個分隔符的輸入流中讀取。
我可以在java中用while循環做到這一點,但我似乎無法弄清楚如何在clojure中做到這一點?
while read readChar != delimiter do some processing.... end while
我不知道的Clojure,但看起來,像方案,它支持「讓循環」:
(loop [char (readChar)]
(if (= char delimiter)
'()
(do (some-processing)
(recur (readChar)))))
希望這是足以讓你開始。我提到http://clojure.org/special_forms#toc9回答這個問題。
注:我知道Clojure不鼓勵副作用,所以大概你想返回一些有用的東西而不是'()。
我想出了line-seq
這個精神。這完全是懶惰的,展現出更多的Clojure的功能性,比loop
。
(defn delim-seq
([#^java.io.Reader rdr #^Character delim]
(delim-seq rdr delim (StringBuilder.)))
([#^java.io.Reader rdr #^Character delim #^StringBuilder buf]
(lazy-seq
(let [ch (.read rdr)]
(when-not (= ch -1)
(if (= (char ch) delim)
(cons (str buf) (delim-seq rdr delim))
(delim-seq rdr delim (doto buf (.append (char ch))))))))))
得到一個更短的方式'ta做到這一點。 – Kzqai 2010-01-09 19:46:56
while循環通常涉及可變變量,即等到變量滿足特定條件; Clojure中你通常用尾遞歸(編譯器轉換成一個while循環)
以下是不完全的解決方案,但for循環的這種變化可能會在某些情況下會有所幫助:
(for [a (range 100)
b (range 100)
:while (< (* a b) 1000)]
[a b]
)
這將創建所有對a和b 的列表,直到(< (* a b) 1000)
。只要條件得到滿足,它就會停止。如果你更換:while with:when,他們可以找到全部滿足條件的對,即使它找到了一個沒有的條件。
上的Clojure 1.3.0工作,併爲它的價值,你可以寫,而用Clojure循環,現在通過做一些類似於
(while truth-expression
(call-some-function))
這依靠一些副作用來使真相表達式最終變成假。 – tenpn 2016-01-25 09:51:55
循環方法將用Clojure但環/易復發做工精細是考慮低級操作和高級功能通常是首選。
通常這類問題會通過創建令牌的序列來解決(在你的例子字符)和應用或更多的Clojure的序列功能(doseq,dorun,採取-while等)
的以下示例從unix類似系統上的/ etc/passwd中讀取第一個用戶名。
(require '[clojure.java [io :as io]])
(defn char-seq
"create a lazy sequence of characters from an input stream"
[i-stream]
(map char
(take-while
(partial not= -1)
(repeatedly #(.read i-stream)))))
;; process the sequence one token at a time
;; with-open will automatically close the stream for us
(with-open [is (io/input-stream "/etc/passwd")]
(doseq [c (take-while (partial not= \:) (char-seq is))]
;; your processing is done here
(prn c)))
我想出了這個版本:
(defn read-until
[^java.io.Reader rdr ^String delim]
(let [^java.lang.StringBuilder salida (StringBuilder.) ]
(while
(not (.endsWith (.toString salida) delim))
(.append salida (str (char (.read rdr))))
)
(.toString salida)
)
)
它尋找一個字符串,而不是單個字符作爲分隔符!
謝謝!
正確的副作用。也許可以在循環中添加一個累加器來顯示如何在功能上構建結果? – 2011-02-19 09:12:47