Сортировка коллекции объектов по номеру (сначала по наибольшему значению), затем по букве (в алфавитном порядке).

StackOverflow https://stackoverflow.com/questions/2232470

Вопрос

Я создаю виджет для отображения количества медалей на Олимпийских играх.У меня есть коллекция объектов «страна», каждый из которых имеет атрибут «имя» и «золото», «серебро», «бронза» для подсчета медалей.

Список должен быть отсортирован:1.Сначала по общему количеству медали 2.Если медали одинаковые, отсортируйте их по типу (золото > серебро > бронза, т. е.Два золота> 1 золото + 1 серебро) 3.Если медали и тип одинаковы, отсортируйте их по алфавиту.

Я делаю это на Ruby, но полагаю, язык не имеет значения.Я нашел решение, но мне кажется, что должен быть гораздо более элегантный способ сделать это.

Вот что я сделал:

  1. Создайте виртуальный атрибут с взвешенной суммой медалей.Таким образом, если бы у них было 2 золота и 1 серебро, взвешенная сумма была бы «3,020100».1 золото, 1 серебро и 1 бронза будут равны «3.010101».

  2. Поскольку мы хотим отсортировать количество медалей сначала по наибольшему, список сортируется по DESC.Но тогда мы хотим выполнить сортировку по алфавиту (т.ASC) после этого.Поэтому я создал функцию, которая инвертирует слово в альфа-канале (т."Канада" => "xzmzwz")

  3. Преобразуйте взвешенную сумму в строку, соедините обратное имя (т.«3010101xzmzwz»), затем отсортируйте по убыванию.Вуаля.

К настоящему моменту кто-то придумал, как сделать то же самое примерно в двух строках кода.Хотите просветить меня?

Это было полезно?

Решение

countries.sort_by do |country|
  medals = country.gold + country.silver + country.bronze
  [-medals, -country.gold, -country.silver, country.name]
end

Другие советы

Простой метод — использовать sort_by с произвольной форматированной строкой, например:

countries.sort_by do |c|
  "%010d-%010d-%010d-%s" % [ c.gold, c.silver, c.bronze, c.name ]
end

Это преобразует все страны в сортируемый список ASCII, добавляя количество выигранных медалей к предположительно возмутительным 10 местам.Если кто-то выиграет более десяти миллиардов медалей, ваша программа может дать сбой, но это кажется разумным ограничением.

В Java вы бы реализовали сопоставимый объект для своего объекта, а затем его можно было бы легко отсортировать в ArrayList или Array.Есть ли в Ruby механизм, позволяющий сравнить два объекта «Страна»?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top