Получение вектора самых больших ключей в векторе карт - PullRequest
4 голосов
/ 25 августа 2011

У меня есть вектор карт, который выглядит следующим образом:

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

5 голосов
/ 25 августа 2011

Вот еще одно решение

user=> (map #(apply max-key :start %) 
            (vals (group-by :game game-vec)))
({:game 1, :start 523456} 
 {:game 2, :start 523456} 
 {:game 3, :start 173456})
3 голосов
/ 25 августа 2011
(into {} (for [[game times] (group-by :game game-vec)]
           {game (apply max (map :start times))}))
2 голосов
/ 25 августа 2011

Я придумал это:

(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 (называемой fmap где-то в contrib) для сопоставления всех значений карты, вероятно, будет даже лучше, но вы можете сделать это самостоятельно)

2 голосов
/ 25 августа 2011

Один из способов - получить все игры от вектора.

может быть что-то вроде:

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

Тем не менее, это всего лишь один из способов, возможно, существуют более эффективные способы в зависимости от определения лучшего.

1 голос
/ 25 августа 2011

Функционально очень похож на код Джулиана Частанга и использует 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 кода Амальлоя является максимально кратким.

1 голос
/ 25 августа 2011

Итерации по моему последнему решению с идеей максимальной функции от @nickik. Я убежден, что где-то здесь есть одна строка: -)

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