我想的Clojure我试图找出如何实现以下算法,

我从我想继续读,直到它不是一个定界符的输入流中读取。

我可以做到这一点在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的阻碍的副作用,所以大概要返回一些有用的东西,而不是“()

其他提示

工作的Clojure 1.3.0,并为它的价值,你现在可以做一些类似于写在Clojure的while循环

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

在环方法将正常工作中的Clojure然而环路/ RECUR被认为是低级别的操作和高阶函数通常是优选的。

通常,这样的问题将通过创建令牌的序列来解决(在你的例子字符)并施加于以上的Clojure的序列的功能(doseq,dorun,取而等)

下面的示例读取从在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)))

我在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))))))))))

全糊

一个while循环通常涉及可变的变量,即,等待到可变满足特定条件; Clojure中你通常使用尾递归(编译器转换成一个while循环)

以下是不完全的解决方案,但for循环的这种变化可能会在某些情况下会有所帮助:

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

这会创建所有的对a和b的直到 (< (* a b) 1000)的列表。这就是它会尽快满足条件停止。如果您要更换:用时:当他们可以找到所有满足条件的,它找到一个即使在对一点不

我想出了这个版本:

(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)
  )
)

它看起来为一个字符串,而不是一个单一的焦炭用作定界符!

谢谢!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top