Сортировка хэша в Ruby сначала по значению, а затем по ключу - PullRequest
1 голос
/ 25 января 2011

Я пытаюсь отсортировать документ по количеству раз, когда слово появляется в алфавитном порядке по словам, поэтому при выводе оно будет выглядеть примерно так:

Unsorted:
'the', '6'
'we', '7'
'those', '5'
'have', '3'

Sorted:
'we', '7'
'the', '6'
'those', '5'
'have', '3'

Ответы [ 7 ]

10 голосов
/ 25 января 2011

Попробуйте:

Предполагая:

a = { 
  'the' => '6', 
  'we' => '7', 
  'those' => '5', 
  'have' => '3', 
  'hav' => '3', 
  'haven' => '3'
}

, после этого:

b = a.sort_by { |x, y| [ -Integer(y), x ] }

b будет выглядеть так:

[
  ["we", "7"], 
  ["the", "6"], 
  ["those", "5"], 
  ["hav", "3"], 
  ["have", "3"], 
  ["haven", "3"]
]

Отредактировано для сортировки по обратным частотам.

3 голосов
/ 25 января 2011
words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3}
sorted_words = words.sort { |a,b| b.last <=> a.last }
sorted_words.each { |k,v| puts "#{k} #{v}"}

производит:

we 7
the 6
those 5
have 3

Возможно, вы хотите, чтобы значения были целыми числами, а не строками для сравнения.

EDIT

Упс, упустили из виду требование, что его тоже нужно отсортировать по ключу. Итак:

words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3,'zoo' => 3,'foo' => 3}
sorted_words = words.sort do |a,b|
  a.last == b.last ? a.first <=> b.first : b.last <=> a.last
end
sorted_words.each { |k,v| puts "#{k} #{v}"}

производит:

we 7
the 6
those 5
foo 3
have 3
zoo 3
1 голос
/ 25 января 2011
histogram = { 'the' => 6, 'we' => 7, 'those' => 5, 'have' => 3, 'and' => 6 }

Hash[histogram.sort_by {|word, freq| [-freq, word] }]
# {
#   'we'    => 7,
#   'and'   => 6,
#   'the'   => 6,
#   'those' => 5,
#   'have'  => 3
# }

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

Кроме того, это предполагает Ruby 1.9.В Ruby 1.8 хэши не упорядочены, поэтому вы не можете преобразовать отсортированный результат обратно в хеш, так как это приведет к потере информации о порядке упорядочения, вам придется хранить ее как массив.

1 голос
/ 25 января 2011

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

words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3}

words.sort { |(x_k, x_v), (y_k, y_v)| [y_v, y_k] <=> [x_v, x_k]}
#=> [["we", 7], ["the", 6], ["those", 5], ["have", 3]]
1 голос
/ 25 января 2011

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

hsh = { 'the' => '6', 'we' => '6', 'those' => '5', 'have' => '3'}
ary = hsh.sort do |a,b|
  # a and b are two element arrays in the format [key,value]
  value_comparison = a.last <=> b.last
  if value_comparison.zero?
    # compare keys if values are equal
    a.first <=> b.first
  else
    value_comparison
  end
end
# => [['have',3],['those',5],['the',6],['we',6]]

Обратите внимание, что результатом являетсямассив массивов, потому что хэши не имеют внутреннего порядка в ruby ​​

0 голосов
/ 25 января 2011

1.9.1

>> words = {'the' => 6,'we' => 7, 'those' => 5, 'have' => 3}
=> {"the"=>6, "we"=>7, "those"=>5, "have"=>3}              
>> words.sort_by{ |x| x.last }.reverse
=> [["we", 7], ["the", 6], ["those", 5], ["have", 3]]
0 голосов
/ 25 января 2011
word_counts = {
        'the' => 6,
        'we' => 7,
        'those' => 5,
        'have' => 3,
        'and' => 6
};

word_counts_sorted = word_counts.sort do
        |a,b|
        # sort on last field descending, then first field ascending if necessary
        b.last <=> a.last || a.first <=> b.first
end

puts "Unsorted\n"
word_counts.each do
        |word,count|
        puts word + " " + count.to_s
end

puts "\n"
puts "Sorted\n"
word_counts_sorted.each do
        |word,count|
        puts word + " " + count.to_s
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...