2011-03-23 77 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) 
相关问题