9

最近、コンソールから日付を繰り返し読み込む必要のある小さなCLIスクリプトを作成しました(読み込む日付の数は計算され、毎回異なる可能性があります)。あなたのアイデアを与えるために、サンプルのRubyコード:ちょうどそれを一体のためコンソールから行を繰り返し読み込むためのClojureコードを書くための慣習的な方法はありますか?

dates = x.times.collect { print "Enter date: "; Date.parse(gets.chomp) } 

は、私はClojureのでスクリプトを書いて、そしてswap!loop...recurといくつかのではなく醜いコードを使用して巻き取りました。私は、Clojureで所望の効果を達成する最もクリーンな方法は何だろうと思っています。 (Clojureのはdotimesを持っているが、それは純粋な関数型プログラミングを強調している言語から予想されるような値が...身体の評価から返され保持されません。)

答えて

7

をあなたの目標は、で終わるのであればその後、ユーザーが入力した正確x日付の順序:

(for [line (repeatedly x read-line)] (DateFormat/parse line)) 

またはを使用して:

(map DateFormat/parse (repeatedly x read-line)) 

はClojureの中に怠惰なシーケンスに注意してください:それらが必要とされているように、ユーザがより多くの日付を入力するように求められます。あなたの目標は(起動時に言って)一度にすべての日付を入力するようにユーザのためであれば、doallを使用します。

(map DateFormat/parse (doall (repeatedly x read-line))) 

これは可能性が一度にすべての日付をを読みますが、それでも遅延し、それらを解析しますので、日付形式の検証あなたのプログラムの後半で失敗します。

(doall (map DateFormat/parse (repeatedly x read-line))) 

そして、あなたは、プロンプトの行を読み取るためにヘルパー関数を使用することができます:あなたは、速やかにも解析するdoall 1つ上のレベルに移動することができます

(defn read-line-with-prompt [prompt] 
    (print prompt) 
    (read-line)) 

が続いてread-lineを置き換え、次のいずれか

#(read-line-with-prompt "Enter date: ") 

または

(partial read-line-with-prompt "Enter date: ") 
+0

偉大な答え...非常に多くのオプションを提供していただきありがとうございます。私は 'read-date'ヘルパー関数を定義し、単に'(repeated x read-date) 'を使うと思います。私はコンソールを使って他に何かをする前に後続の処理が評価されると思うので、 'doall'はおそらく*必要ないでしょうが、それを私のツールキットに入れてもいいと思うし、それは後で。 –

4

をあなたはこのような何か行うことができます。

(defn read-dates [n] 
    (doall (for [_ (range n)] (java.util.Date/parse (read-line))))) 

(def my-dates (read-dates 5)) ;Read 5 dates from console 
10

ファイルの終わりに達すると、read-lineはnilを返します。あなたがCTRL-d (WindowsではCTRL-z)を押すときのコンソールで

あなたはこの機能を利用するために、このコードを使用することができます。

(doseq [line (repeatedly read-line) :while line] 
    (do-something-with line)) 

あなたが行の固定数を読まなければならない場合は、使用することができます。

(repeatedly n read-line) 
+1

'doseq'で':while'を使うのは面白いですが、これまで見たことはありません。クール! – dimagog

関連する問題