2

比較用のシーケンスが2つあり、比較結果をマップに保持する必要があります。最初のシーケンスのデータはキーとして機能し、2番目のシーケンスは値として機能します。動作するサンプルコードがあります

(def myAtom  (atom {}))

(map #(if (== %1 %2) (swap! myAtom assoc %1 %2 ))
              [1 2 3]   [4 5 3]) 

(prn @myAtom)  ; ==>  {3 3}

ただし、上記の「同じ」ものを1つのletバインディングに入れると、機能しなくなります。

(let  [ myAtom  (atom {})]    
  (map #(if (== %1 %2) (swap! myAtom assoc %1 %2 ))
              [1 2 3]   [4 5 3]) 
  (prn @myAtom)) ;;==> {} empty???

だから問題は、letbinding内のmyAtomはどうなるのかということです。どうして行方不明なの?

4

2 に答える 2

7

mapシーケンスから遅延シーケンスを生成することですが、必要なのはシーケンス内の各アイテムに対して特定の操作(つまりスワップ)を行うことです。したがって、使用する必要がありますdoseq

編集:(@mobyteの提案に従って更新)

(let  [myAtom  (atom {})
       a [1 2 3]
       b [4 5 3]]    
  (doseq [[x y] (map vector a b)]
    (if (== x y) (swap! myAtom assoc x y )))
  (prn @myAtom))

最初の例が機能するのは、REPL で各式を実行し、map 操作で遅延操作を実行したためです。

多くの人が map を使用してこのような特定の操作を行おうとしているのを見てきましたが、map は 1 つの目的にのみ使用する必要があります。つまり、副作用操作なしでシーケンスを別のシーケンスにマッピングします。

于 2013-03-11T06:34:43.790 に答える
4

Ankur が述べたようにdoseq、命令型操作に使用することをお勧めします。

(let [myAtom  (atom {})]    
  (doseq [[a b] (map vector 
                     [1 2 3]
                     [4 5 3])]
    (when (== a b) (swap! myAtom assoc a b )))
  (prn @myAtom))

dorunただし、元のバージョンで次を使用して、マップ結果の評価を強制できます。

(let  [ myAtom  (atom {})]    
  (dorun (map #(when (== %1 %2) (swap! myAtom assoc %1 %2 ))
              [1 2 3] [4 5 3])) 
  (prn @myAtom))

PS Ankur のバージョンはオリジナルのものと同等ではありません

doseq:

(doseq [a [1 2 3]
        b [4 5 3]]
  (println [a b]))

=> [1 4]
   [1 5]
   [1 3]
   [2 4]
   [2 5]
   [2 3]
   [3 4]
   [3 5]
   [3 3]

map:

(dorun (map #(println [%1 %2]) 
            [1 2 3]
            [4 5 3]))

=> [1 4]
   [2 5]
   [3 3]
于 2013-03-11T08:30:07.737 に答える