Я предполагаю, что количество каждой буквы не зависит от регистра.
str = "Apple, Banana, Time, Time, Time, Banana Apple, Time."
Вы сказали, что сортируете по «количеству вхождений на символ» (например, не по «букве»).Вы можете сделать это следующим образом.
h = str.downcase.
each_char.
each_with_object(Hash.new(0)) { |c,h| h[c] += 1 }.
sort_by { |_,v| -v }.
to_h
#=> {"a"=>8, " "=>7, "e"=>6, ","=>6, "i"=>4, "t"=>4, "m"=>4, "p"=>4,
# "n"=>4, "b"=>2, "l"=>2, "."=>1}
Если требуется только количество букв, есть еще один шаг:
h.select { |k,_| k.match?(/[a-z]/i) }
#=> {"a"=>8, "e"=>6, "i"=>4, "t"=>4, "m"=>4, "p"=>4, "n"=>4, "b"=>2, "l"=>2}
Этот последний шаг, конечно, можно связать с вычислениемиз h
выше.
Шаги следующие:
a = str.downcase
#=> "apple, banana, time, time, time, banana apple, time."
b = a.each_char
#=> #<Enumerator: "apple, banana, time, time, time, banana apple,
# time.":each_char>
Мы можем видеть элементы, которые перечислитель c
сгенерирует и передаст в блок, преобразовав его в массив.
b.to_a
#=> ["a", "p", "p", "l", "e", ",", " ", "b", "a", "n", "a", "n",
# "a", ",", " ", "t", "i", "m", "e", ",", " ", "t", "i", "m",
# "e", ",", " ", "t", "i", "m", "e", ",", " ", "b", "a", "n",
# "a", "n", "a", " ", "a", "p", "p", "l", "e", ",", " ", "t",
# "i", "m", "e", "."]
Продолжение,
c = b.each_with_object(Hash.new(0)) { |c,h| h[c] += 1 }
#=> {"a"=>8, "p"=>4, "l"=>2, "e"=>6, ","=>6, " "=>7, "b"=>2,
# "n"=>4, "t"=>4, "i"=>4, "m"=>4, "."=>1}
d = c.sort_by { |_,v| -v }
#=> [["a", 8], [" ", 7], ["e", 6], [",", 6], ["i", 4], ["t", 4],
# ["m", 4], ["p", 4], ["n", 4], ["b", 2], ["l", 2], [".", 1]]
e = d.to_h
#=> {"a"=>8, " "=>7, "e"=>6, ","=>6, "i"=>4, "t"=>4, "m"=>4,
# "p"=>4, "n"=>4, "b"=>2, "l"=>2, "."=>1}
e.select { |k,_| k.match?(/[a-z]/i) }
#=> {"a"=>8, "e"=>6, "i"=>4, "t"=>4, "m"=>4, "p"=>4, "n"=>4,
# "b"=>2, "l"=>2}
Последний шаг можно пропустить, если вычисление a
было изменено на следующее.
a = str.downcase.gsub(/[^a-z]/i, '')
#=> "applebananatimetimetimebananaappletime