My array is
fruits = [["apple", "Tue"], ["mango", "Mon"], ["apple", "Wed"], ["orange", "Tue"]]
The result I want to get is to Group by Fruit and the count
[["apple", 2], ["mango", 1], ["orange", 1]]
I have always worked with just a single array when I wanted to group elements, how to work with array of arrays?
fruits.group_by {|(fruit, day)| fruit }.map {|fruit, match| [fruit, match.count] }
fruits = [["apple", "Tue"], ["mango", "Mon"], ["apple", "Wed"], ["orange", "Tue"]]
fruits.group_by(&:first).map{|k,v| [k,v.size]}
# => [["apple", 2], ["mango", 1], ["orange", 1]]
Your example format looks a lot like a hash. If it's OK to have a hash, then you can do this.
count = Hash.new(0)
fruits.each { |f| count[f.first] += 1 }
# => {"apple"=>2, "mango"=>1, "orange"=>1}
Then you can just convert it to an array.
count.to_a
# => [["apple", 2], ["mango", 1], ["orange", 1]]
EDIT
As a side note, defining the hash as Hash.new(0)
means that the default value is 0
instead of nil
. This is how we get away with not defining any of the hash keys first.
EDIT 2
With Arup's suggestion this turns into
counts = fruits.each_with_object(Hash.new(0)) { |f, h| h[f.first] += 1 }
Depends on your preferences. I find the first a little easier to read.
Being late to the party, I find the hors d'oeuvres nearly gone. Alas, I'm left with just a crumb:
f = fruits.map(&:first).sort
f.uniq.zip(f.chunk(&:dup).map(&:size)) # => [["apple", 2], ["mango", 2], ["orange", 2]]
# => [["apple", 2], ["mango", 2], ["orange", 2]]
Had I been more punctual, I would have grabbed one of those yummy group_by
tarts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With