2009-06-28 7 views
11

내가 Clojure에 나는 다음과 같은 알고리즘을 구현하는 방법을 알아 내려고 노력하고 있어요 시도,Clojure의 루프

나는 내가 그것을 구분 기호 문자가 아닌 때까지 계속 읽고 싶은 입력 스트림에서 읽기하고있다.

while 루프를 사용하여 java에서이 작업을 수행 할 수 있지만 clojure에서 수행하는 방법을 알아낼 수 없습니다.

 
while 
    read 
    readChar != delimiter 

    do some processing.... 
end while 

답변

10

나는 Clojure의 모르지만, 그것은 계획처럼, 그것은 "루프를하자"지원 것으로 보인다 : 이것은 당신이 처음 사용하기에 충분한

(loop [char (readChar)] 
    (if (= char delimiter) 
     '() 
     (do (some-processing) 
      (recur (readChar))))) 

희망을. 나는이 질문에 대답하기 위해 http://clojure.org/special_forms#toc9을 언급했다.

참고 : Clojure가 부작용을 저지른다는 것을 알고 있으므로 아마도 '() 대신 유용한 것을 반환하고 싶을 것입니다.

+0

부작용에 관하여. 어쩌면 누산기를 루프에 추가하여 결과가 기능적으로 어떻게 구축되는지 보여줄 수 있습니까? –

2

나는 이것을 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)))))))))) 

Full paste.

+0

이렇게하는 것이 더 짧습니다. – Kzqai

1

while 루프는 일반적으로 가변 변수를 포함합니다. 즉 변수가 특정 조건을 충족 할 때까지 대기합니다.

: Clojure의 당신은 일반적으로

다음은 꽤 솔루션이 아니라, 대한 루프의 변화가 어떤 경우에 도움이 될 수있다 (컴파일러가 잠시 루프로 변환) 꼬리 재귀를 사용하십시오

(for [a (range 100) 
     b (range 100) 
     :while (< (* a b) 1000)] 
    [a b] 
) 

이 은(< (* a b) 1000) 때까지 모든의 쌍과 B 의 목록을 작성합니다. 그것은 조건이 충족 되 자마자 멈출 것입니다. : while : with :를 바꾸면 모두가 조건을 충족하는 쌍 중 하나를 찾지 못한 경우에도 찾을 수 있습니다.

5

Clojure의 1.3.0에서 작업, 그것은 가치가 무엇 지금

(while truth-expression 
    (call-some-function)) 
+0

이것은 진리 표현이 결국 거짓이되게하는 몇 가지 부작용에 의존합니다. – tenpn

3

루프 방식에 가깝다 뭔가를 수행하여 Clojure의에서 루프 Clojure의 그러나 루프/RECUR에서 잘 작동하는 동안, 당신은 쓸 수에 대한 낮은 수준의 작업과 높은 순서 기능이 일반적으로 선호되는 것으로 간주됩니다. 일반적으로 이러한 종류의 문제점은 토큰의 시퀀스를 생성하여 해결 될 것

합니다 (예 : 문자) 및 또는 Clojure에서의 시퀀스 기능 (doseq, dorun, 테이크 동안, 등)

의 더 적용 다음 예제는 시스템과 같은 유닉스에서/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))) 
0

나는이 버전으로 나온 :

그것은 문자열이 아닌 구분 기호로 단일 문자를 찾습니다
(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) 
) 
) 

!

감사합니다.