Ruby / RoR - подсчитать вхождение элемента в массив - PullRequest
16 голосов
/ 20 декабря 2010

Я хэш

{1=>true, 7=>false, 6=>true, 4=>false}

или массив типа

[1, true], [7, false], [6, true], [4, false]]

или

[true, false, true, false].

Как узнать количество true с в массиве?

Ответы [ 6 ]

23 голосов
/ 20 декабря 2010

Чтобы посчитать элементы, вам, очевидно, нужно перебрать коллекцию. Поскольку итерация по 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)
6 голосов
/ 20 декабря 2010

С Enumerable # count :

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) }
4 голосов
/ 20 декабря 2010

Упрощенно:

hash.values.count(true)

array.flatten.count(true)

Это работает со всеми вышеперечисленными случаями.

1 голос
/ 20 декабря 2010

В одну сторону (ваш хэш должен был бы вызвать .to_a, чтобы это сработало):

[[1, true], [7, false], [6, true], [4, false]].flatten.select{|s| s == true }.size
1 голос
/ 20 декабря 2010

Для хэшей:

{ :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
0 голосов
/ 07 июня 2019

Ruby 2.7 +

Ruby 2.7 представляет Enumerable#tally (и, возможно, tally_by) для этой конкретной цели.Вот хорошее резюме здесь .

Здесь обсуждается вопрос о том, будет ли окончательная реализация использовать tally или tally_by при предоставлении блока, как здесь.

Inэтот сценарий использования:

# or hash.tally_by if that's the accepted method for block form
hash.tally { |k, v| v }
# => { true => 2, false => 2 }

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...