2011-11-17 10 views
8

私はClojureを初めて使いました。私は最近、私が学習の助けとして最近したデータ操作を翻訳してきました。私はうまく動作し、短いですが、はるかに少ない読み込みを感じる関数の翻訳があります。誰もがこれを処理するために、より読みやすく、かつ/またはより慣用的な方法を提案できますか? PythonでClojureでこのシーケンス変換を処理する最良の方法は何ですか?

:Clojureの翻訳で

def createDifferenceVector(v,startWithZero=True): 
    deltas = [] 
    for i in range(len(v)): 
     if i == 0: 
      if startWithZero: 
       deltas.append(0.0) 
      else: 
       deltas.append(v[0]) 
     else: 
      deltas.append(v[i] - v[i-1]) 
    return deltas 

私の試み:

(defn create-diff-vector [v start-zero] 
    (let [ext-v (if start-zero 
       (cons (first v) v) 
       (cons 0 v))] 
    (for [i (range 1 (count ext-v))] 
     (- (nth ext-v i) (nth ext-v (- i 1)))))) 

それが理由だけではClojureとの私の経験不足の読みにくくだが、特に中に、トリックているかもしれません入力ベクトルに要素を付加することは、それが意図を不明瞭にするように私に感じます。私が試したプリペイド・トリックを使わなかったすべての解決策は、はるかに長くて醜いものでした。

Clojureでは多くのシーケンス変換が非常にエレガントですが、これまでのところ難しいと思われるものは、a)要素ではなくインデックスによる操作に適している、および/またはb)特別な処理が必要なもの特定の要素については

ありがとうございます。

答えて

12

イディオム的なClojureは、個々の要素ではなく、全体として配列を操作する傾向があります。結果は、以下からなるベクトルである

:あなたのように英語でcreate-diff-vectorを定義することができstart-zeroは、それぞれ、真であるか偽であるかに依存し、

  • ゼロまたは入力の最初の要素。第1要素のない入力シーケンスと最後の要素のない入力シーケンスとの間の差異が続く。

第二部は以下のようなものを例示することができる:入力(31 41 59 26 53)のために、我々はClojureのに翻訳され、

 
    input without the first element: (41 59 26 53) 
- input without the last element: (31 41 59 26) 
=================================================== 
    result:       (10 18 -33 27) 

を持っている、非常に簡潔に次のようになります。

(defn diff-vector [v start-zero?] 
    (into [(if start-zero? 0 (first v))] 
    (map - (rest v) v)))) 

注意すべきいくつかのポイント:

  • 01の末尾に疑問符はここでブール値が期待されるというヒントとなります。
  • このコードでは、異なる長さのシーケンスにわたって関数mapがpingを実行すると、最短シーケンスの終わりに終了するという事実を利用しています。
+2

非常にクールです。私はいつも '(map foo x(rest x))'事を忘れる - 私は通常 '([ab(パーティション2 1 v)]( - ba) ) '。地図ははるかによかったです。 – amalloy

+0

ありがとうございます。それは本当に明確な説明であり、それを表現するより洗練された方法です。私にはClojureの考え方を取り上げるのに時間がかかりますが、私はすでに報酬を見ています。 – eggsyntax

+0

Heh。 5年後、現在プロのClojure/scriptデベロッパー、私はちょうどこれをまたがって実行しました。独自にソリューションを書いたところ、あなたのものとほぼ同じ言葉で終わった@daniel。当時私が正しい経路に乗るのを手伝ってくれてありがとう – eggsyntax

1

この実装は、より慣用のようになります。私は、第1の入力ベクトルに最初のベクトルの値または0のいずれかを付加

(defn create-diff-vector [v start-with-zero?] 
    (let [v (cons (if start-with-zero? (first v) 0) v)] 
     (map - (rest v) v))) 

。次に、mapを使用して、1つの位置だけシフトしたベクトルを減算します。

関連する問題