2

私は clojure プログラミングが初めてで、少し助けが必要です。示されているようなマップのベクトルがあるとします。

(def testVMap 
  [ {:name "AAA" :rate 100 } 
    {:name "GEICO" :rate 120 }
    {:name "PROGRESSIVE" :rate 118} ] )

AAA のレートを見つける、または ALLSTAR などのレートがあるかどうかを確認するなどの操作を行うにはどうすればよいですか。レートが存在しない場合は、追加できるようにする必要があります。しかし、私の主な関心事は、マップに特定の名前があり、名前が存在する場合はレートを新しい値に更新する必要があることです。

4

3 に答える 3

2

1 つの方法を次に示します。

(some #(if (= "GEICO" (:name %)) %) testVMap)

testVMapつまり、 が:nameと等しい最初のものを返し"GEICO"ます。 を関数パラメータとして#(... % ...)関数を定義します。%この部分は、各マップの値(:name %)の値を返します。:name

複数の「GEICO」マップが存在する可能性があり、それらすべてが必要な場合は、filter代わりにsome.

別のバージョンは次のとおりです。

 (some #(and (= "GEICO" (:name %)) %) testVMap)

あなたも使いたくなるかもしれませんupdate

編集:例:

(map #(if (= "GEICO" (:name %))
          (update % :rate inc)
          %)
testVMap)

これincは、数値に 1 を加算する関数です。同じものである #(+ 10 %)、 またはなど、必要な変換を実行する関数に置き換える必要があります。(partial + 10)

によって定義された関数#(...)は、の値が「GEICO」であるかどうかをチェックし:name、そうであれば、指定した関数でレートを更新します (incこの場合)。それ以外の場合#(...)は、マップを変更せずに返します。

updateコンテキストから自明でない場合は、のドキュメントを調べるのはあなたに任せます。

mapvの代わりに使用することもできますmap

これらすべてを 1 つ以上の関数に組み込みたいと思うことは間違いありません。関数は Clojure のものであることを思い出してください。それらは「データ」、ファースト クラス オブジェクトなどですinc。関数はupdate、コードの一部で (代わりにinc) を使用します。

必要なマップが存在しない場合のマップの追加について: 長い一連のマップを扱っていない場合は、別の手順でこれを行うことを検討します。コレクションに要素が含まれているかどうかをテストするのに役立つ関数の名前については、Andre の回答を参照してください。

ただし、ベクトルに存在しないものが含まれているかどうかをテストするには、Clojure がベクトル全体を調べる必要があることに注意してください。ベクトルではなく Clojure セットを使用するか、(たとえば) 、 などをキーとして外側のマップを使用することを検討することをお勧め:aaa:geicoます。その場合は、関数を見てくださいupdate-in

于 2015-09-08T18:28:31.473 に答える
1

これを行う方法をすぐに説明する代わりに、この種の関数を見つける方法をお見せしましょう。

これらの 2 つの Web サイトは、機能をうまく構成しています。

今あなたが扱っているのは一般的にコレクションであり、それがあなたが望むことをしない場合は、特定のベクトル操作を探すことができます. しかし、最初はコレクションでなければなりません。両方のサイトにコンテンツ テストセクションが表示されます。

現在、次の候補があります。

distinct? empty? every? not-every? some not-any?

ここでの正しい候補は次のsomeとおりです。

(some (comp (partial = "AAA") :name) testVMap)
;; => true
于 2015-09-08T18:28:56.290 に答える
1

アイテムが存在するかどうかを確認する

(first
  (filter
    (comp #{"AAA"} :name)
    [{:name "AAA" :rate 100}
     {:name "GEICO" :rate 120}
     {:name "PROGRESSIVE" :rate 118}]))

構造の更新

順序が重要でない場合は、構造を name->rate のマップに再編成できます。例えば:

{"AAA" 100 "GEICO" 120}

update-in次に、またはを使用assocしてレートを更新できます。

順序重要な場合は、次のようにすることができます。

(mapv
  (fn [{:keys [name] :as v}]
    (if (= name "AAA")
      (assoc v :rate 500)
      v))
  [{:name "AAA" :rate 100}
   {:name "GEICO" :rate 120}
   {:name "PROGRESSIVE" :rate 118}])

構造への追加

シンプルなconj. だからあなたは次のようなことをします

(if (has-item? struct) ;; has-item would be defined using the first section of this answer
  (update-item struct ...) ;; update-item using the second section of this answer
  (conj struct {:name "AAA" :rate 100}))

もちろん他にも選択肢はありますが、私が最初に行くのはこれらです。

于 2015-09-08T18:29:01.723 に答える