Ваш sorted
га sh можно записать немного более кратко, как:
sorted = arr.map { |x| [x, arr.count(x)] }.to_h
Для массива примера [1, 1, 2, 2, 3]
это эквивалентно:
[
[1, arr.count(1)], # counts all 1's in arr
[1, arr.count(1)], # counts all 1's in arr (again)
[2, arr.count(2)], # counts all 2's in arr
[2, arr.count(2)], # counts all 2's in arr (again)
[3, arr.count(3)] # counts all 3's in arr
].to_h
Мало того, что он учитывается 1
и 2
дважды. Он также должен пересекать весь массив снова для каждого count
вызова (или select
в вашем коде).
Лучший подход - обойти массив один раз и использовать га sh для подсчета вхождений:
arr = [1, 1, 2, 2, 3]
sorted = Hash.new(0)
arr.each { |x| sorted[x] += 1 }
sorted #=> {1=>2, 2=>2, 3=>1}
Это также можно записать в одну строку через each_with_object
:
sorted = arr.each_with_object(Hash.new(0)) { |x, h| h[x] += 1 }
#=> {1=>2, 2=>2, 3=>1}
Ruby 2.7 даже есть специальный метод tally
для подсчета случаев:
sorted = arr.tally
#=> {1=>2, 2=>2, 3=>1}