在地图矢量中获取最大键矢量

时间:2011-08-25 16:09:54

标签: vector map clojure key

我有一张地图矢量,如下所示:

(def game-vec [{:game 1 :start 123456}
        {:game 2 :start 523456}
        {:game 3 :start 173456}
        {:game 1 :start 123456}
        {:game 1 :start 523456}
        {:game 2 :start 128456}
        {:game 3 :start 123256}])

我想为每个:start花费最多的:game时间。最好的方法是什么?

6 个答案:

答案 0 :(得分:5)

这是另一种解决方案

user=> (map #(apply max-key :start %) 
            (vals (group-by :game game-vec)))
({:game 1, :start 523456} 
 {:game 2, :start 523456} 
 {:game 3, :start 173456})

答案 1 :(得分:3)

(into {} (for [[game times] (group-by :game game-vec)]
           {game (apply max (map :start times))}))

答案 2 :(得分:2)

一种方法是从矢量中获取所有游戏。

可能是这样的:

(defn game-keys [from]
    (set (map (fn [x] (:game x)) from)))

现在我们将所有独特的游戏存储在某个地方,现在我们希望每个人都能获得最高价值的游戏。如果我们过滤掉正确的游戏,排序可能会有用。

(defn games [key from] 
  (filter (fn [x] (= (:game x) key)) from))

所以我们可以获得我们想要的游戏,现在我们只需要最高的游戏

(defn max-start [lst]
  (first (sort (fn [x y] (> (:start x) (:start y))) lst))) 

现在我们可以做到:

(map (fn [x] (max-start (games x game-vec))) (game-keys game-vec))

然而,这只是一种做法,根据最佳定义,可能有更好的方法。

答案 3 :(得分:2)

我想出了这个:

(defn max-start-per-game [coll]  
        (into {} (map (fn [[k v]] [k (apply max (map :start v))]) 
                      (group-by :game game-vec))))

=> (max-start-per-game game-vec)
{1 523456, 2 523456, 3 173456}

我们的想法是将每场比赛的所有数据放在一个地方,然后取出数据作为开始。然后就这样做了最多。

更通用的版本:

(defn collect [coll sum-key collect]
  (into {} (map (fn [[k v]] [k (map :start v)])
                (group-by :game game-vec))))

(defn no-good-name
  [coll f key1 key2]
  (into {} (map (fn [[k v]] [k (f v)])
                (collect coll key1 key2)))


(no-good-name game-vec #(apply max %) :game :start)
 => {1 523456, 2 523456, 3 173456}

(使用costum函数(在contrib中某处称为fmap)来映射地图的所有值可能会更好,但你可以做到这一点)

答案 4 :(得分:1)

使用@nickik中的max function idea迭代我的上一个解决方案。我确信在这里有一个单行: - )

(reduce                                                                                                                                                                                                                                     
 (fn [m x]                                                                                                                                                                                                                                  
   (assoc m (:game x)                                                                                                                                                                                                                       
          (max (:start x)                                                                                                                                                                                                                   
               (or (m (:game x)) 0))))                                                                                                                                                                                                      
 {}
 game-vec)

答案 5 :(得分:1)

功能上非常类似于Julian Chastang的代码并使用reduce我有:

(defn max-start-per-game [games]
  (reduce (fn [res {:keys [game start]}]
    (let [cur-start (get res game 0)
          max-start (max start cur-start)]
      (assoc res game max-start))) 
    {} 
    games))
user=> (max-start-per-game game-vec)
{3 173456, 2 523456, 1 523456}

或者使用group-by amalloy的代码尽可能简洁。