11

私はハッシュマップを持っています。値を反復処理し、値のタイプに応じてそれぞれを置き換えたいと思います。値が整数のtrue場合は に置き換え、そうでない場合は に置き換えfalseます。これにより、すべての値が true または false に更新された新しいハッシュマップが返されます。

(defn my-function [hash-map]
  (loop [hash-map hash-map]
    (for [value (vals hash-map)]
      (if (= Integer (type value))
        (recur (assoc hash-map key true))
        (recur (assoc hash-map key false))))))

Clojure のため、それは機能しませんCan only recur from tail positionが、それが私がやりたいことの一般的な考え方です。これを行うための効果的な方法のアイデアはありますか? if-let潜在的な解決策のようにupdate-in思えましたが、私はそれらを完全に把握することはできません.

4

4 に答える 4

18
(reduce-kv (fn [m k v] (assoc m k (= Integer (type v)))) {} m)

または、必要に応じてさらに短くします。

(reduce-kv #(assoc %1 %2 (= Integer (type %3))) {} m)

マップのタイプ (ハッシュとソート) を維持するには:

(reduce-kv #(assoc %1 %2 (= Integer (type %3))) (empty m) m)

警告: 最後のものはレコードでは機能しません。

于 2013-01-30T07:32:00.927 に答える
5

概説した操作 (マップ内の各値を個別に変換する) は、実際には既にFunctor モジュールに実装されています。

それを使用するために必要なことは、単一の値を変換する関数を実装してから、fmapそれをマップに適用することです。

(fmap your-function your-map)

(fmap という名前に惑わされないでください。この操作はマップに固有のものではありません。これは一般的な関数であるため、リスト、セット、およびベクトルを含む Functor インスタンスを持つすべてのもので機能します)。 これは構造を維持する操作です。キーは変更されず、新しいキーは追加されず、削除されません。

汎用関数の使用を避けたい場合は、実装を確認してください。

(defmethod fmap clojure.lang.IPersistentMap
  [f m]
  (into (empty m) (for [[k v] m] [k (f v)])))  ;;; <== the important part!!

どこf = your-functionm = your-map


このライブラリは に移動されました (移動しますか? 移動しますか?) clojure.algo.generic.functor。詳細についてはこちらを、ソースについてはこちらを参照してください。

于 2013-01-30T11:51:39.437 に答える
3
(letfn [(map-vals [m f]
          (into {} (for [[k v] m]
                     [k (f v)])))]
  (map-vals m #(= Integer (type %))))
于 2013-01-30T06:46:24.617 に答える
0
(defn f [m]
  (reduce (fn [res [k v]] 
            (assoc res k (= Integer (type v)))) 
          {} m))

または、再帰バージョンが必要な場合

(defn f 
  ([m] (f {} m))
  ([res m] (if (empty? m)
             res
             (let [[k v] (first m)]
               (recur (assoc res k (= Integer (type v))) 
                      (rest m))))))
于 2013-01-30T07:19:33.750 に答える