Як сортувати Ruby Hash за значенням числа?


154

У мене зустрічний хеш, який я намагаюся сортувати за кількістю. Проблема, з якою я стикаюся, полягає в тому, що функція Hash.sort за замовчуванням сортує числа як рядки, а не за розміром числа.

тобто з огляду на хеш:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }

Запуск цього коду:

metrics.sort {|a1,a2| a2[1]<=>a1[1]}

поверне відсортований масив:

[ 'siteb.com', 9, 'sitea.com', 745, 'sitec.com', 10]

Незважаючи на те, що 745 - це більша кількість, ніж 9, 9 у списку з’явиться першим. Коли я намагаюся показати, хто має найкращий підрахунок, це ускладнює моє життя. :)

Будь-які ідеї, як сортувати хеш (або масив навіть) за розміром значення числа?

Я вдячний за будь-яку допомогу.


яку рубінову версію ви використовуєте? результат сортування дуже дивний
fl00r

Відповіді:


268

Поняття не маєте, як ви отримали свої результати, оскільки це не буде сортувати за значенням рядка ... Ви повинні перевернути a1і a2у своєму прикладі

Найкращий спосіб у будь-якому випадку (за Младеном):

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
  # ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

Якщо вам потрібен хеш, ви можете використовувати to_h(в Ruby 2.0+)

metrics.sort_by {|_key, value| value}.to_h
  # ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}

84
або простоsort_by{|k,v| v}
Младен Ябланович

Мій номер повертався як рядок, що його виправляв .. У мене було a2 та a1 у такому порядку, тому що я хотів, щоб результати сортували обман .. дякую за ваш відгук.
Дастін М.

ось чому я люблю Рубі ... така проблема - це біль у голові іншими мовами. так просто
Хаді Ельзахар

18
@Elchin: можна скористатисяmetrics.sort_by{ |k, v| v }.reverse.to_h
Марк-Андре Лафортун

4
Насправді навіть простіше, як: hash.sort_by (&: last) з тим же застереженням щодо отримання масиву пар проти Hash.
Геррі Глісон


14

Вже відповів, але все ж. Змініть код на:

metrics.sort {|a1,a2| a2[1].to_i <=> a1[1].to_i }

Перетворений на рядок по дорозі чи ні, це зробить роботу.


9

Це не та поведінка, яку я бачу:

irb(main):001:0> metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" =>
 10 }
=> {"siteb.com"=>9, "sitec.com"=>10, "sitea.com"=>745}
irb(main):002:0> metrics.sort {|a1,a2| a2[1]<=>a1[1]}
=> [["sitea.com", 745], ["sitec.com", 10], ["siteb.com", 9]]

Чи можливо, що десь уздовж рядка ваші номери перетворюються на рядки? Чи є ще код, який ви не публікуєте?


Ах, ваше право, схоже, що результат у моєму коді повертав його як рядок. Пескі типи даних. :) Іноді я просто занадто близький до проблеми. Дякую.
Дастін М.

1
Так. Інколи я чую, як хтось називає Рубі як "нетиповий". О, ні, це напевно набрано. Це просто не набрано статично. :)
Якоб Меттісон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.