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 }

Документы на выпускаемые функции находятся здесь.

Надеюсь, это поможет кому-то!