Java Clojure While循环
我正在尝试clojure我正在尝试找出如何实现以下算法 我正在读取输入流,我希望继续读取,直到它不是分隔符为止 我可以在java中通过while循环来实现这一点,但我似乎不知道如何在clojure中实现这一点 while read readChar != delimiter do some processing.... end while 虽然 阅读 readChar!=分隔符 做一些处理。。。。 结束时Java Clojure While循环,java,clojure,loops,while-loop,Java,Clojure,Loops,While Loop,我正在尝试clojure我正在尝试找出如何实现以下算法 我正在读取输入流,我希望继续读取,直到它不是分隔符为止 我可以在java中通过while循环来实现这一点,但我似乎不知道如何在clojure中实现这一点 while read readChar != delimiter do some processing.... end while 虽然 阅读 readChar!=分隔符 做一些处理。。。。 结束时 我不知道Clojure,但它看起来像Scheme一样,支持“let循环
我不知道Clojure,但它看起来像Scheme一样,支持“let循环”: 希望这足以让你开始。我提到要回答这个问题
注意:我知道Clojure不鼓励副作用,所以你可能想返回一些有用的东西,而不是“()”。我是本着
line seq
的精神提出这个建议的。它完全是惰性的,比循环
更能体现Clojure的功能性
(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(范围100))
b(射程100)
:while(<(*ab)1000)]
[甲、乙]
)
这将创建a和b的所有对的列表,直到
(<(*ab)1000)
。也就是说,它将在满足条件后立即停止。如果将:while替换为:when,您可以找到满足条件的所有对,即使在找到不满足条件的对之后也是如此。正在Clojure 1.3.0上工作,而且值得一提的是,您现在可以在Clojure中编写while循环,方法类似于
(while truth-expression
(call-some-function))
循环方法在clojure中可以很好地工作,但是循环/重现被认为是低级操作,通常首选高阶函数 通常,这类问题可以通过创建令牌序列(示例中的字符)并应用clojure的一个或多个序列函数(doseq、dorun、take while等)来解决 下面的示例在类unix系统上从/etc/passwd读取第一个用户名
(需要'[clojure.java[io:as-io]]
(定义字符顺序)
“从输入流创建惰性字符序列”
[i-stream]
(映射字符
(花点时间
(部分非=-1)
(反复地#(.读i-stream()(#))))
;; 一次处理一个令牌序列
;; 使用open将自动为我们关闭流
(打开[is(io/input stream)/etc/passwd”)]
(doseq[c(take-while(partial-not=\:)(char-seq-is))]
您的处理在这里完成
(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)
)
)
它寻找一个字符串,而不是一个字符作为分隔符
谢谢 应该是一个较短的方法来做这件事。关于副作用。也许可以在循环中添加累加器,以显示结果是如何在功能上构建的?这依赖于一些副作用,使真值表达式最终变为假。
(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)
)
)