Ruby/RoR - подсчет количества элементов в массиве
I'v хэш
{1=>true, 7=>false, 6=>true, 4=>false}
или массив вроде
[1, true], [7, false], [6, true], [4, false]]
или
[true, false, true, false]
.
Как я могу найти число true
в массиве?
Ответы
Ответ 1
Чтобы подсчитать элементы, вам, очевидно, придется перебирать коллекцию. Поскольку итерация по Hash
дает двухэлементный Array
s, первые два на самом деле точно такие же:
{ 1 => true, 7 => false, 6 => true, 4 => false }.count(&:last)
[[1, true], [7, false], [6, true], [4, false]].count(&:last)
Для простого случая Array
вы можете сделать что-то вроде этого:
[true, false, true, false].count(true)
Этот Array
, конечно, также совпадает с Hash#values
от вашего Hash
выше, поэтому вы можете использовать тот же метод:
{ 1 => true, 7 => false, 6 => true, 4 => false }.values.count(true)
Если вы не знаете, какой из трех вы получите, вы можете использовать что-то вроде этого:
{ 1 => true, 7 => false, 6 => true, 4 => false }.flatten.count(true)
[[1, true], [7, false], [6, true], [4, false]].flatten.count(true)
[true, false, true, false].flatten.count(true)
Ответ 2
С Перечисляемый # счетчик:
hash.values.count(true)
array_of_pairs.map { |k, v| v }.count(true)
plain_array.count(true)
Более подробный, но не создает промежуточные массивы:
hash_or_array_of_pairs.inject(0) { |acc, (k, v)| acc + (v == true ? 1 : 0) }
Ответ 3
Simpler:
hash.values.count(true)
array.flatten.count(true)
Это работает со всеми вышеперечисленными случаями.
Ответ 4
Для хэшей:
{ :a => true, :b => true, :c => false }.select{ |k,v| v }.length
=> 2
Для массивов:
[true, false, false, true, true].select{ |o| o }.length
=> 3
Другой способ (тестирование с отрицанием):
[true, false, false, true, true].reject{ |o| o != true }.length
=> 3
Ответ 5
Один из способов (ваш хэш понадобился бы .to_a
, чтобы он первым работал над ним):
[[1, true], [7, false], [6, true], [4, false]].flatten.select{|s| s == true }.size
Ответ 6
Рубин 2. 7+
Ruby 2.7 представляет Enumerable#tally
(и, возможно, tally_by
) для этой конкретной цели. Здесь хорошее резюме здесь.
Здесь обсуждается, будет ли окончательная реализация использовать tally
или tally_by
при предоставлении блока, как здесь.
В этом случае использования:
# or hash.tally_by if that the accepted method for block form
hash.tally { |k, v| v }
# => { true => 2, false => 2 }
Документы на выпускаемые функции находятся здесь.
Надеюсь, это поможет кому-то!