2014-10-03 4 views
2

У меня есть функция, которая возвращает следующую карту массива:Возвращение Высших пар ключей значения внутри массива Карты в Clojure

{{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}} 

И я хотел бы вернуться 2, так как он имеет самый высокий ключ, 499. Каков наилучший способ сделать это?

+1

возможно дубликат [Возвращаемое значение самого высокого ключа в Clojure] (http://stackoverflow.com/questions/ 26146366/return-value-of-high-key-in-clojure) – RedDeckWins

ответ

2

Не самый эффективный способ, если ваша карта является большим, но это работает:

(def am {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}) 

(->> am (map key) (sort-by first) last vals first) 

=> 2 
+0

Но зачем сортировать весь список, когда достаточно пройти один проход? – Mark

+0

Нет причин, это была моя первая мысль. Возможно, это немного более читаемо, чем решение max-key. Если карта коротка, сортировка теряется в шуме. Если он большой, то, конечно, лучше всего сделать один проход. –

+0

Ну, я все еще думаю, что OP выбрала неправильную структуру данных в любом случае, решение, когда ввод - это просто карта, абсолютно ясна и читаема. Я не могу понять, почему можно использовать такую ​​карту карт (или массив карт), где каждое отображение - всего лишь пара значений. – Mark

1
((comp val first key) 
(apply max-key 
     (comp key first key) 
     {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}})) 

Это находит значение первого (по спецификации единственный?) Запись в карте с самым высоким первый ключ.

0

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

[{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}] 

В этом случае эта функция возвращает ваше желает значение:

(defn val-for-highest-key 
    [s] 
    (->> s (map #(into [] %)) (map first) (apply max-key first) second)) 

тест:

(def res [{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}]) 
(val-for-highest-key res) 

результат:

=> 2 
+0

с вводом в качестве вектора вектора, '(второй (применить max-key (сначала ключ comp)))'. 'flatten' здесь не называется (на самом деле он редко подходит). – noisesmith

+0

О, спасибо. Я удалил 'flatten'. –

+0

Но зачем сортировать весь список, когда достаточно пройти один проход? – Mark

1

Если вы хотите представлять отношения между числами, вам не нужна карта карт. Вы, вероятно, нужно одну карту, как это:

user> (def foo {498 3, -498 3, 99 2, -99 2, 499 2, -499 2, 100 1, -100 1}) 
;; => #'user/foo 

Это путь более идиоматических, поверьте, так может быть, вы должны рассмотреть функцию, которая возвращает карту карты (или вектор карт) переписывания.

Чтобы решить вашу проблему, попробуйте использовать max-key, так как это эффективная функция, созданная специально для таких случаев. Вот как вы можете использовать его с картой:

user> (second (apply max-key first foo)) 
;; => 2 
+0

Мне дана карта карт, а не одна карта, на которую вы ее сменили. Так что этот ответ не работает. – user3245240

+0

Этот ответ основан на рекомендации. Что значит «мне дана карта карт»? Вы имеете в виду, что вы получаете карту карт из какой-либо функции, которую вы не можете изменить? Я сомневаюсь, потому что нет необходимости в такой структуре данных. Карта может содержать много пар «ключ -> значение», поэтому вы можете получить значение 3 с ключом 498 и значением 2 с ключом 99 или -99 с использованием одной единственной карты. Если вы не должны использовать ключ '{498 3}' для получения значения '{-498 3}', то в такой организации данных абсолютно нет смысла. Это не идиоматично. Даже если вы хотите получить '{-498 3}' с помощью ключа '{498 3}', вы можете написать функцию, которая – Mark

+0

... просто отрицает первый элемент карты. Скажите, пожалуйста, почему вы должны использовать карту карт? – Mark

0

Попробуйте это:

(let [fval (comp val first) 
     fkey (comp key first)] 
    (fval 
    (reduce 
    (fn [v e] (if (< (fkey v) (fkey e)) e v)) 
    (keys {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}})))) 
Смежные вопросы