【问题标题】:Getting a vector of largest keys in vector of maps获取地图向量中最大键的向量
【发布时间】:2011-08-25 16:09:54
【问题描述】:

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

(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}])

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

【问题讨论】:

    标签: vector map clojure key


    【解决方案1】:

    这是另一个解决方案

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

    【讨论】:

    • 我真的很喜欢这让问题变得多么简单。它也是破坏性最小的,因为它保留了可能存在的任何其他密钥!
    【解决方案2】:
    (into {} (for [[game times] (group-by :game game-vec)]
               {game (apply max (map :start times))}))
    

    【讨论】:

      【解决方案3】:

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

      可能是这样的:

      (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))
      

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

      【讨论】:

      • (map (fn [x] (:game x)) from) 是 smae as (map :game form)
      【解决方案4】:

      我想出了这个:

      (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)来映射地图的所有值可能会更好,但您可以自己做)

      【讨论】:

        【解决方案5】:

        使用@nickik 的最大函数想法迭代我的最后一个解决方案。我确信这里的某个地方有一条单线 :-)

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

        【讨论】:

          【解决方案6】:

          在功能上与 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-byamalloy 的代码尽可能简洁。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-11-27
            • 1970-01-01
            • 1970-01-01
            • 2021-05-07
            • 2015-10-11
            • 2014-09-13
            • 2012-04-10
            相关资源
            最近更新 更多