ID = -> x { x } # Why is the identity function not in the core lib?
f = <<-HERE
0101
1010
1311
0101
1311
431
1010
431
420
HERE
Hash[f.lines.map(&:to_i).group_by(&ID).map {|n, ns| [n, ns.size] }]
# { 101 => 2, 1010 => 2, 1311 => 2, 431 => 2, 420 => 1 }
Вы просто группируете числа по отдельности, используя Enumerable#group_by
, что дает вам что-то вроде
{ 101 => [101, 101], 420 => [420] }
А затем вы Enumerable#map
массив значений на их длины, т. Е. [101, 101]
становится 2
. Затем просто конвертируйте его обратно в Hash
, используя Hash::[]
.
Однако, если вы хотите использовать стороннюю библиотеку, она становится еще более тривиальной, поскольку, если вы используете структуру данных MultiSet
, ответ естественно выпадает. (A MultiSet
похож на Set
, за исключением того, что элемент можно добавлять несколько раз, а MultiSet
будет вести подсчет того, как часто элемент добавлялся - это именно то, что вам нужно.)
require 'multiset' # Google for it, it's so old that it isn't available as a Gem
Multiset[*f.lines.map(&:to_i)]
# => #<Multiset:#2 101, #2 1010, #2 1311, #2 431, #1 420>
Да, все.
Это замечательная вещь при использовании правильной структуры данных: ваши алгоритмы становятся намного проще. Или, в данном конкретном случае, алгоритм просто исчезает .
Я написал больше об использовании MultiSet
s для решения этой точной проблемы на
- найти повторение повторяющихся чисел. (первый пример в этом посте такой же, как второй здесь, второй пример в этом посте, по сути, такой же, как @ Чака здесь и третий такой же, как первый в этом посте.)
- Подсчет вхождений уникальных букв в строке (пример Ruby такой же, как здесь, примеры Scala и ECMAScript такие же, как @ Chuck's, а пример C # такой же, как мой
group_by
пример здесь.)
- Bag / Multiset в scala и немного мультикарты (Опять те же три примера, что и мои два и @ Chuck's в Scala.)