2013-08-14 3 views
6

は、私はこれをやってみたかった:clojure.stringのsplitとjoinの引数の位置が混ざっているのはなぜですか?

(-> string 
    (str/split "\s") 
    (modification-1) 
    (modification-2) 
    … 
    (modification-n 
    (str/join "\n")) 

しかし、いや、分割は[s regex]かかり、[seperator coll]を取る参加します。

この狂気には明らかな理由はありませんか(読んでください:これの背後にあるデザインの決定は何ですか?)

+1

と間違っている何が? ( "\ n"(分割文字列 "\ s")を結合する) – Chiron

+0

私はいくつかの修正関数を間に入れなかった。明確にするためにそれらを追加する。 – Profpatsch

+0

なぜですか? 'clojure.string.join'はコレクションを取る他の関数と一貫しています。 '(map f col)(filter f col)' –

答えて

8

Clojure 1.5では、新しいスレッド化マクロの1つを使用することもできます。

clojure.core /ままの>

([exprの&形態をNAME])

マクロ

バインド名exprに、その語彙文脈 で最初のフォームを評価バインドした後、その結果に名前をバインドし、最後に返されたフォームの結果を返します。

それはかなり新しい構造ですので、まだ慣用的に使用する方法がわからが、私はこのような何かをするだろうと思います。なぜ引数の位置については

(as-> "test test test" s 
    (str/split s #" ") 
    (modification-1 s) 
    (modification-2 s) 
    ... 
    (modification-n s) 
    (str/join "\n" s)) 

編集

私はどこにも言えませんが、アーサーの示唆は意味をなさないと思います。

  • 一部の機能は、コレクション(明らかにmapreduceなど)で動作します。これらは、一貫して、彼らはいくつかの機能がコレクションで動作し、最も重要な引数を取る傾向がない->>
  • でうまく動作を意味し、最後の引数としてコレクションを取る傾向にある(ですその事?)最初として引数。たとえば、/を使用する場合、分子が最初に来ることが予想されます。これらの機能は、最もよく機能します

事はいくつかの機能があいまいです。彼らはコレクションをとり、単一の値を生成するか、単一の値をとりコレクションを生成することがあります。 string\splitは1つの例です(文字列が単一の値またはのコレクションの両方と考えることができるというさらなる混乱を無視してください)。連結/縮小操作もそれを行います - 彼らはあなたのパイプラインを台無しにするでしょう!

は、例えば、考えてみましょう:これらのケースでは

(->> (range 1 5) 
    (map inc) 
    (reduce +) 
    ;; at this point we have a single value and might want to... 
    (- 4) 
    (/ 2)) 
    ;; but we're threading in the last position 
    ;; and unless we're very careful, we'll misread this arithmetic 

が、私はas->のようなものは本当に便利だと思います。

私は、一般的にコレクションや->上で動作している場合->>を使用するためのガイドラインはそうでない音だと思う - そしてそれはこれらの境界線/あいまいな場合にだけだ、as->はコード少し明確少しすっきり、作ることができます。

+2

この新しいマクロが大好きです。これを行うことができる図書館がありました。それが「コア」に到着するのを見て嬉しいです。 – Profpatsch

+3

これは古い方法よりもはるかに優れており、読んだときに欠落した引数を想像する必要がないため、コードを読みやすくしています。 –

+0

[tag:forth]のトーチを持っているので、私はスレッドマクロが大好きですが、引数の順序を操作するために 'swap'、' roll'、 'dup'のスレッド同等のものを秘密に望んでいました。まぁ。 –

2

部分関数を使用して、str/joinのseparator引数を修正することができます。

(-> string 
    (str/split #"\s") 
    (modification-1) 
    (modification-2) 
    ;; 
    (modification-n) 
    ((partial str/join "\n"))) 
+0

私はそれが部分的なフォームに文字列を置くと思います。括弧で囲みますか? –

+0

することもできます...(変更-n)( - >>(str/join "\ n")))) –

+0

本当にうまくいくのですか?変更-nの結果は、部分的にstr/joinの前にスレッド化されているようです。 – Blacksad

2

私はまた、この種の(マイナーな)スレッディング頭痛をかなり規則的に流します。

(-> string 
    (str/split "\s") 
    (modification-1) 
    (modification-2) 
    … 
    (modification-n 
    (#(str/join "\n" %))) 

となり、多くの場合、順序が一致するように匿名関数が作成されます。私の推測によると、その理由はいくつかの関数は最初にスレッドで使用することを意図していたのですが、->、最後には->>というスレッドがあり、スレッドの一部は設計目標ではありませんでした。

+0

これはすべての関数で機能し、質問に対する答えを見つけようとするため、これを受け入れます。 – Profpatsch

+0

2番目の矢印は ' - >>'でなければなりません。 – Profpatsch

+0

固定:-) *ブラッシュ* –

0

このように、別のスレッドのマクロを通して、あなたのネジ式のスレッドには何もありません:

(-> string 
    (str/split "\s") 
    modification-1 
    modification-2 
    modification-n 
    (->> (str/join "\n"))) 
関連する問題