2016-04-15 15 views
2

私は、交互のセットと数値で構成されるカスタムデータ構造で重複を説明する機能的なソリューションを考え出しています。カスタムクロージャーベクトルの重複を考慮する

例:

(def a [#{:a} 0.1 #{:b} 0.3 #{:a :b} 0.1 #{:a} 0.3 #{:b} 0.1 #{:a} 0.1]) 

私は

[#{:a} 0.5 #{:b} 0.4 #{:a :b} 0.1] 

をもたらすためにセットを複製するために対応する値が、私はloop/recurを使用してこれを行うことができます追加したいが、使用方法がある場合には思っていましたClojureの高次関数です。

ありがとうございました。

+1

ループ/反復ソリューションを共有できますか? – jmargolisvt

+0

ペアの順序は重要ですか?そうでない場合は、キーワードのセットから数字のシーケンス(ベクトル?)までのマップとしてデータを保持できます。 – Thumbnail

答えて

1

私は、ソースベクトルを、数値の集計として機能するキーマップに折りたたんだり、展開してベクトルに戻したりします。

(->> a 
    (partition 2) 
    (reduce (fn [acc [k v]] 
       (if (get acc k) 
       (update acc k (partial + v)) 
       (assoc acc k v))) 
      {}) 
    (reduce (fn [acc [k v]] 
       (into acc [k v])) 
      [])) 
5
(reduce 
    (fn [acc [k v]] 
    (update acc k (fnil + 0) v)) 
    {} 
    (partition 2 a)) 

まず、partition、その後reduceそれらのペアで、キーと値のペアにあなたの順序を分割します。このトリックは、accにまだ追加されていないキーに対しては、0のキーの代わりにnilを置き換えるfnilを使用することです。あなたが値のフラットなシーケンスとしてそれを必要とする場合は

{#{:a} 0.5, #{:b} 0.4, #{:b :a} 0.1} 

あなたはseqflattenを通してそれを渡すことができます::(ちょうど楽しみのため

(->> a 
    (partition 2) 
    (reduce 
    (fn [acc [k v]] 
     (update acc k (fnil + 0) v)) 
    {}) 
    (apply concat) 
    (into [])) 

;; => (#{:a} 0.5 #{:b} 0.4 #{:b :a} 0.1) 
+0

私は前に 'fnil'を使ったことがありません。それを指摘していただきありがとうございます。非常にエレガント。 – endbegin

+0

あなたは歓迎です:)。私はあなたがマップではなく、一連の値を必要としていることを見落としました。私は私の答えを更新しました。 –

+0

私はあなたの答えを「受け入れられた」とマークしていないことを知っていますが、それはあります。私は両方として受け入れられることを願っています。 – endbegin

4

1つの以上の変異体をあなたのマップを与える

なぜならreduceバージョンが明らかに優れた性能を持っているからです)。

(->> a 
    (partition 2) 
    (group-by first) 
    (map (fn [[k v]] [k (apply + (map second v))])) 
    (reduce into [])) 
関連する問題