当前位置: 动力学知识库 > 问答 > 编程问答 >

How to write clojure conditional statements

问题描述:

How can one translate the following code

while ((readInteger = fileInputStream.read()) != -1) {

.....

}

in clojure ? I need the value of readInteger in further parts of the code but also the '!= -1' needs to take place inside the while conditional.

网友答案:

some general patterns for adapting things to the Clojure syntax

  1. move the ( to the left of the function or opperator.
  2. move opperators to the left of the things they work on and surround with ( )

so you could start like this:

(while (not= (.read fileInputStream) -1 ... and so on.

then, since you need to use the readInteger value later in the code let's talk about naming values and looping. If you just wanted to read a value once and give it a name you could do it like this:

(let [readInteger  (.read fileInputStream)]
  ... your code here)

Since you want to do it in a loop, then let's use loop instead of let:

(loop [readInteger  (.read fileInputStream)]
  ... your code here
  (if (not= readInteger -1)
    (recur (.read fileInputStream))))

or for (which is not the "for loop" from other languages)

(for [readInteger   (repeatedly #(.read fileInputStream))
      :while (not= readInteger -1)]
  ... do somethign with readInteger ...)

For generates sequences of results rather than just looping like it does in other languages.

Then the next step in clojuring is to think about how to split the reading the data from processing it. We can:

  1. make a sequence of all the data
  2. process each data

something like this:

(let [data (line-seq fileInputStream)]
  (map #(Integer/parseInt %) data)
  ...)

There are functions in the standard library for converting a great many things into sequences, and a bunch of functions for doing a great many things with sequences.

网友答案:

Don't solve this problem with while, which requires you to do your test at the beginning of the loop. Instead, think about a recursive function, which can decide at any part of its body whether to make the recursive call or not. Any iterative loop can be converted into a tail-recursive function using loop/recur; here's an example of how to do it with your loop.

(loop []
  (let [read-integer (.read file-input-stream)]
    (when (not= read-integer -1)
      (...)
      (recur))))
网友答案:

Here are two similar examples like amalloy suggested:

(ns xyz...
  (:require  [clojure.java.io :as io] )
  (:import [java.io StringReader] ))

(newline) (newline)
(let [reader-2 (io/reader (StringReader. "first")) ]
  (loop []
    (let [curr-char-int (.read reader-2)]
      (when (not= -1 curr-char-int)
        (print (char curr-char-int) " ")
        (recur)))))

(newline) (newline)
(let [reader-2 (io/reader (StringReader. "second")) ]
  (loop [curr-char-int (.read reader-2)]
    (when (not= -1 curr-char-int)
      (print (char curr-char-int) " ")
      (recur (.read reader-2)))))

With result:

> lein run

f  i  r  s  t  

s  e  c  o  n  d  

In the first case it takes an extra let statement, but doesn't duplicate the part (.read reader-2) like the 2nd case does.

网友答案:

Using threading macro:

(->> (repeatedly #(.read fs))
     (take-while (partial not= -1))
     (map str))

Replace (map str) with whatever function you want to operate on the stream. For example, to calculate the sum:

(->> (repeatedly #(.read fs))
     (take-while (partial not= -1))
     (reduce +))
分享给朋友:
您可能感兴趣的文章:
随机阅读: