У меня есть список, который мне нужно отсортировать по самым популярным элементам. Есть ли способ сделать это?
После повторной сортировки мне также необходимо избавиться от дубликатов. У меня есть идея функции для этого, но она кажется неэффективной, поэтому есть встроенные методы, чтобы помочь с этим?
[1,5,4,6,4,1,4,5].group_by {|x| x}.sort_by {|x,list| [-list.size,x]}.map(&:first) => [4,1,5,6]
Как это?
Метод Array#sort принимает необязательный предикат для сравнения двух элементов, поэтому ...
Array#sort
list.sort { |a, b| a.popularity <=> b.popularity }
Для устранения дубликатов используйте Array#uniq.
Array#uniq
list.uniq
Чтобы склеить их,
list = list.sort { |a, b| a.popularity <=> b.popularity }.unique
Или просто
list.sort! { |a, b| a.popularity <=> b.popularity }.uniq!
Большинство из этих ответов не сработали для меня, за исключением Гленна Макдональдса (до тех пор, пока я не опубликовал этот ответ). Я нашел ответ на свой вопрос где-то еще, как этот
Метод uniq принимает блок, поэтому вы можете указать, какое «свойство» вашего объекта должно быть uniq.
new_list = list.sort_by{|el| el.popularity}.uniq{|el| el.popularity}
Итерация по списку для создания хэша, который отображает item -> number of times, нужно всего лишь одно посещение всех элементов списка, тогда операции с хешем будут иметь постоянное время, поэтому O (n), что не кажется таким дорогим.
item -> number of times