2016-06-28 4 views
2

私はRuby配列の配列を取得し、その値を数えるためにグループ化しようとしています。Rubyの配列グループと数値による集計

アレイは、月を持っており、ブール:

array = [["June", false], ["June", false], ["June", false], ["October", false]] 

私は私に知らせて、新たな配列で終了するようになるどのように多くの偽の各月のtrues対。

例:(配列中の最初の項目は月であり、第二が偽と第三のカウント値が真のカウント数である)Enumerable#group_byを使用

new_array = [["June", 3, 0]], ["October", 1, 0]] 

答えて

1

Array.group_by { |month, b| month }.map{ |month, xs| 
    [month, 
    xs.count {|_, b| !b}, # false 
    xs.count {|_, b| b}] # true 
} 
# => [["June", 3, 0], ["October", 1, 0]] 
+0

'Enumerable#group_by'は配列ではなくハッシュを返します。 –

+0

@Jordanだから、私は 'map'呼び出しで戻り値をチェーンしました。 (さらに「真」、「偽」を数えるために処理が必要) – falsetru

+0

ああ、そうでした。私の悪い。 –

-2
Array.group_by {|(Array, boolean)| Array }.map {|Array, match| [Array, match.count] } 
+2

あなたはこのコードを試してみましたか?それは動作しないことを知っていますか? –

+0

次のエラーがスローされます。仮引数は定数ではありません – perezdr

0

reduce操作では、これが良い使用例になると思います。

arr = [["June", false], ["June", false], ["June", false], ["October", false]] 
logical_group = Hash.new{|h, k| h[k] = Hash.new(0) } 

arr.reduce(logical_group) do |red, ele| 
    red[ele.first][:false_count] += 1 unless ele.last 
    red[ele.first][:true_count] += 1 if ele.last 
    red 
end.reduce([]) do |red, (key, value)| 
    red << [key, value[:false_count], value[:true_count]] 
    red 
end 
0

Enumerable#group_byは便利なツールですが、この場合には、それは最高のものではありません。あなたのような何かをするだろう。

デフォルト値が[0, 0]のHashで始める場合は、月を調べる(またはデフォルトの値を新しい月にする)ことができます。適切なインデックスに1を加えます(0 falseそして、真のため1)シングルステップ-in:あなたはそれを投稿する前に

array = [["June", false], ["June", false], ["June", false], ["October", false]] 

hsh = Hash.new {|h,k| h[k] = [0,0] } 
array.each {|mo, bool| hsh[mo][bool ? 1 : 0] += 1 } 

p hsh.map(&:flatten) 
# => [["June", 3, 0], ["October", 1, 0]] 
+0

これも同様に機能します。なぜそれはEnumerable#group_byより良いですか? – perezdr

+0

'group_by'では、データを4回反復する必要があります。一度はグループ化を行い、一度は' true'を数え、もう一度 'false'のために、さらにハッシュを配列に変換します。上記では、我々は2度だけ反復する必要があります:1回はカウントを行い、もう1回はそれを配列に変換します。 –

+0

ok、明日あなたの答えvs falsetru'sでそれをテストします。 – perezdr

0
array.map(&:dup) # we’ll mutate it 
    .group_by(&:shift) 
    .flat_map { |k, v| [k, v.partition { |e| e }.map(&:count)] } 
#⇒ [ ['June', [0, 3] ], ['October', [0, 1] ] ] 
関連する問題