2

アソシエーションは、ベクトル/マップのインデックス/キーで値を変更できます。マップでは、キーが存在しない場合、新しいキーと値のペアが作成されます。ベクトルに似たようなものはありますか (インデックスが存在しない場合、そのインデックスでその値を持つリストを作成します)。

 (reduce (fn [g [x y]] (assoc-in g [x y] y ))
        []
        (for [x (range 2) 
              y (range 2)]
             [x y]))

上記のコードは以下を生成します:

[{1 1, 0 0} {1 1, 0 0}]

私はそれを生成したい:

[[0 1] [0 1]]

これは簡単な方法で可能ですか?

ありがとう

編集:より明確にするために、ネストされたマップ(またはマップのベクトル)の代わりにネストされたベクトルを生成するようにしたいだけです。yを値として入力しますが、これは単なる例です。

4

2 に答える 2

6

マップではなくベクターを作成すると、ベクター内assocの既存のインデックスまたは次のインデックスしか作成できないため、一般的なケースではうまく機能しません。

user=> (assoc [:a] 0 :b) ; works because index 0 exists
[:b]
user=> (assoc [:a] 1 :b) ; works because index 1 is next
[:a :b]
user=> (assoc [:a] 2 :b) ; fails since index is out of range
IndexOutOfBoundsException   clojure.lang.PersistentVector.assocN (PersistentVector.java:136)

とはいえ、気をつけていればまだまだ活躍できます。の実装は次のassoc-inとおりです。

(defn assoc-in
  [m [k & ks] v]
  (if ks
    (assoc m k (assoc-in (get m k) ks v))
    (assoc m k v)))

条件getの true 分岐を呼び出すことに注意してください。if代わりにベクトルを使用する独自のバージョンが必要な場合assoc-inは、 によって返されるデフォルト値として空のベクトルを追加できますget

(defn vassoc-in
  [m [k & ks] v]
  (if ks
    (assoc m k (vassoc-in (get m k []) ks v))
    (assoc m k v)))

質問のサンプル コードではvassoc-inなくを使用すると、希望どおりになります。assoc-in[[0 1] [0 1]]

于 2012-11-02T15:46:43.760 に答える
0

次のようなものが必要なようです:

user=> (let [cv #(apply vector %)] 
         (cv (map cv (repeat 5 (range 2)))))
[[0 1] [0 1] [0 1] [0 1] [0 1]]
于 2012-11-02T15:32:11.217 に答える