11

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?

4 Answers 4

10
fruits.group_by {|(fruit, day)| fruit }.map {|fruit, match| [fruit, match.count] }
Sign up to request clarification or add additional context in comments.

1 Comment

If anyone else is looking for the direct documentation: ruby-doc.org/core-2.3.3/Enumerable.html#method-i-group_by
8
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]]

Comments

4

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.

4 Comments

The way you are using your code,I would suggest go with each_with_object.
or fruits.reduce(Hash.new(0)) {|count,f| count[f.first] += 1; count}.to_a.
Don'y you love the Hash.new(0)! It's like the best Ruby thing I've found this month.
I keep forgetting about each_with_object. I prefer it to reduce/inject here and in similar situations, because there is no need to return an object to the iterator, which probably also reduces bugs.
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.