2011-03-23 56 views
9

什麼是簡單/優雅的方式放入一個映射鍵值對的相應條件爲真?有條件地將鍵值放入地圖中,簡潔的方法是什麼?

這是翻譯

[condition1 condition2 ...] [key1 val1 key2 val2 ...] 

[condition1 condition2 ...] [key1 key2 ...] [val1 val2 ...] 

[condition1 key1 val1 condition2 key2 val2...] 

{key-for-true-condition1 val-for-true-condition1, key-for-true-condition2 val-for-true-condition2...} 

我認爲在lambda中用「if」來「減少」,但對更簡潔/美觀/優雅/習慣方式感興趣。

回答

6
(into {} (for [[c k v] (partition 3 coll) :when c] 
    [k v])) 

基於金太郎的'for'版本,但稍短。

1
(def coll [true :key1 "value1" false :key2 "value2" true :key3 "value3"]) 

(defn testpair [[cond key val]] 
    (when cond 
     {key val})) 

(apply merge (map testpair (partition 3 coll))) 
=> {:key3 "value3", :key1 "value1"} 

這將是一種方式,但如果您想要條件鍵和值的其他組合,您必須更改代碼。你沒有提到女巫會是最好的。

編輯: 由於其第一清單上

(def conditions [true false true]) 
(def keyval [:key1 "value1" :key2 "value2" :key3 "value3"]) 

(defn testpair [cond [key val]] 
    (when cond 
     {key val})) 

(apply merge (map testpair conditions (partition 2 keyval))) 

因爲它的樂趣:)

(def conditions [true false true]) 
(def keys [:key1 :key2 :key3]) 
(def vals ["value1" "value1" "value3"]) 


(defn testpair [cond key val] 
    (when cond 
     {key val})) 

(apply merge (map testpair conditions keys vals)) 
3

說實話海事組織,版本 reduceif已經是最優雅和慣用的 見下面nickik的評論。

(def coll [true :a "v1" false :b "v2" true :c "v3"]) 

(reduce (fn [a [c k v]] (if c (assoc a k v) a)) {} (partition 3 coll)) 

下面是使用一個版本的修真第三種情況:

(apply array-map (flatten (for [[c k v] (partition 3 coll) :when c] 
          [k v]))) 

編輯:

爲你把它轉換成第三種情況第二種情況下這樣做:

(def c [true false true]) 
(def k [:a :b :c]) 
(def v ["v1" "v2" "v3"]) 

(def coll (interleave c k v)) 

但我認爲從nickik map版本在這裏比較好。

+3

Mhh很好。我想出了一些更好的東西(我認爲): ({{(for [[ckv](partition 3 coll):when c] [kv])) – nickik 2011-03-23 14:46:08

+0

啊我知道有更好的方法來獲得從鍵值向量列表中的地圖:) – Kintaro 2011-03-23 15:00:35

+0

我認爲減少的例子是壞的,因爲它真的很難閱讀。在這種情況下,使用'for'是最好的。 – nickik 2011-03-23 16:10:00

2

我首先會想到它是如何成爲最好的功能操作在流圖:

  1. 組條件/鍵/值成塊
  2. 篩選塊中條件不成立
  3. 下降的條件
  4. 拼合塊
  5. 從結果
創建地圖

它看起來像:

(def coll [true :a "v1" false :b "v2" true :c "v3"]) 

(apply hash-map 
    (flatten 
    (map #(drop 1 %) 
     (filter #(first %) 
     (partition 3 coll))))) 

或者,如果你感覺纖維性:

(->> coll 
    (partition 3) 
    (filter #(first %)) 
    (map #(drop 1 %)) 
    flatten 
    (apply hash-map)) 

我不知道這是優雅簡潔還是,但我認爲這很容易閱讀。請注意,如果你經常用這種形狀的數據處理,你可能會發現類似的步驟(分3科爾)或(第一個%)可能是他們自己的權利有用的可重複使用的功能,從而導致類似:

(defn condition-group [coll] (partition 3 coll)) 
(defn condition [group] (first group)) 
(defn but-condition [group] (drop 1 group)) 
(defn kv-map [kv-pairs] (apply hash-map (flatten kv-pairs))) 

(->> coll 
    condition-group 
    (filter condition) 
    (map but-condition) 
    kv-map) 
相關問題