Возвращаемое значение самого высокого ключа в Clojure

Я работаю с этими двумя группами пар ключ-значение, которые возвращаются другой функцией. Я хотел бы написать функцию, которая всегда будет находить наивысший ключ и возвращать соответствующее значение. В этом примере я бы вернул 2, потому что 499 — самый высокий ключ. Данные, с которыми я работаю,

({-99 0, 99 0} {-99 2, 499 2})

Когда я звоню

   (type ({-99 0, 99 0} {-99 2, 499 2}))

В функции, которая отвечает за возврат этих данных, я получаю обратно

 (clojure.lang.PersistentTreeMap clojure.lang.PersistentTreeMap)

Надеюсь, это поможет. Спасибо!


person user3245240    schedule 01.10.2014    source источник
comment
видимо ты имеешь в виду (map type pair)   -  person Leon Grapenthin    schedule 01.10.2014
comment
Как вы хотите разрешить повторяющиеся максимальные ключи?   -  person Jeremy    schedule 02.10.2014


Ответы (5)


Эта функция вернет самую правую запись отсортированной карты Clojure (встроенная реализация называется clojure.lang.PersistentTreeMap) за логарифмическое время:

(defn rightmost
  "Takes a Clojure sorted map sm and returns the entry at the greatest
  key (as determined by sm's comparator)."
  [sm]
  (first (rseq sm)))

Пример:

(rightmost (sorted-map 1 1 2 2 3 3))
;= [3 3]

Затем вы можете извлечь значение, используя функцию val.

Вместо этого все решения на основе max-key/apply max работают в линейном времени. Излишне говорить, что это огромная разница.

Если бы другую функцию можно было убедить вернуть карты data.avl, вы могли бы получить доступ к элементу по адресу любой индекс в логарифмическом времени с использованием nth:

;; works for data.avl sorted maps, not the built-ins
(nth (avl/sorted-map 1 1 2 2 3 3) 2)
;= [3 3]
person Michał Marczyk    schedule 01.10.2014

(as-> (apply merge pair)
      merged
      (->> merged
           keys
           (apply max)
           merged))

Обратите внимание, что когда обе карты имеют «самый высокий» ключ, возвращается значение второго.

person Leon Grapenthin    schedule 01.10.2014

Это хороший вариант использования max-key (см. этот другой вопрос SO для хорошего примера ее использования), имя которого, как мне кажется, вводит в заблуждение — на самом деле он берет функцию и коллекцию и возвращает элемент в коллекции, который имеет наивысший результат применения функции. к этому пункту. Вы можете использовать функцию key, которая возвращает ключ пары ключ-значение.

(Обратите внимание, что вам нужно объединить ваши карты, чтобы вы работали с одной коллекцией пар ключ-значение.)

(apply max-key key (concat {-99 0, 99 0} {-99 2, 499 2}))
;=> [499 2]

(second *1)
;=> 2
person Dave Yarwood    schedule 01.10.2014
comment
Я хотел бы отметить, что самое правое значение будет выбрано при наличии повторяющихся ключей. (apply max-key key (concat {-99 0, 499 0} {-99 2, 499 2})) ;=> [499 2] - person Jeremy; 02.10.2014
comment
Вы правы... это вызовет проблемы, если крайний правый ключ не имеет наивысшего значения. Интересно, что (concat {-99 0, 499 5} {-99 2, 499 2}) сам по себе возвращает список, который действительно содержит повторяющиеся ключи: ([-99 0] [499 5] [-99 2] [499 2]). Однако выполнение (apply max-key key ... поверх этого, по-видимому, приводит эти ключи к java.util.Map$Entry парам ключ-значение и устраняет дубликаты, переходя к крайнему правому, и вы получаете неверный (обратите внимание, что я изменил крайний левый, сделав его значение › 2) ответ [499 2] . - person Dave Yarwood; 02.10.2014
comment
На самом деле, при дальнейшем рассмотрении, [499 2] технически не является неправильным - OP просто искал способ вернуть значение для самого высокого key, равного 499. Таким образом, проблема в том, что есть два значения для этого ключа. В любом случае, я по-прежнему считаю max-key хорошим решением, если вы работаете с одной картой без повторяющихся ключей. - person Dave Yarwood; 02.10.2014
comment
Правильно, это не неправильно. (Вот почему я не проголосовал против ;-)) Я просто хотел отметить детали реализации, потому что, если есть повторяющиеся максимальные ключи, есть более одного ответа. Ваш алгоритм разрешает это определенным образом, даже если это часть реализации! - person Jeremy; 02.10.2014
comment
Мне нравится ход твоих мыслей! :) - person Dave Yarwood; 02.10.2014

(defn val-for-max-key [maps]
  (->> (map (partial apply max-key key) maps)
       (apply max-key key)
       val))

РЕДАКТИРОВАТЬ: неправильно поняли желаемое возвращаемое значение

person RedDeckWins    schedule 01.10.2014

({-99 0, 99 0} {-99 2, 499 2}) — операция поиска, где {-99 0, 99 0} — словарь, а {-99 2, 499 2} — ключ. Поскольку последний не является ключом первого, выражение вернет nil.

Когда я оцениваю (type ({-99 0, 99 0} {-99 2, 499 2})), я получаю nil, потому что тип nil также nil.

person user100464    schedule 01.10.2014
comment
Это не операция, это список, возвращаемый другой функцией. - person Leon Grapenthin; 01.10.2014