Merkelst
Merkelst

Reputation: 311

Counting the number of repeated elements in an array

Controller:

@user_location = Country.joins(:user).order(:name).compact.uniq

View (haml):

- @user_location.each do |user|
  %li= user.name

At this point, all duplicate elements of the array are deleted (uniq).

How can I display the number of repetitive elements in the array? For example: if my array has

One Two Two Three Four

then I need to show

One Two (2) Three Four

Upvotes: 0

Views: 535

Answers (4)

nautgrad
nautgrad

Reputation: 414

You need group_by + map. Like this:

array.group_by(&:itself).map do |k, v|
 { value: k, count: v.length }
end

You will have array of hashes like this: {value: 'Two', count: 2}.

You can return data in any desired way. However, it's much better to get grouped records directly from SQL.

Upvotes: 2

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

%w[One Two Two Three Four].
  group_by{|x|x}.
  map{|k, v|[k,v.count>1?" (#{v.count})":nil]}.
  map(&:compact).
  map(&:join)
#⇒ ["One", "Two (2)", "Three", "Four"]

Upvotes: 0

SRack
SRack

Reputation: 12203

You can iterate through using each_with_object, counting elements as they're assigned to a hash key. For example:

array = %w(One Two Two Three Four)

counts = array.each_with_object(Hash.new(0)) do |el, hash| 
  hash[el] += 1
end
# => {"One"=>1, "Two"=>2, "Three"=>1, "Four"=>1}

counts.map { |k, v| v > 1 ? "#{k} (#{v})" : k }
# => ["One", "Two (2)", "Three", "Four"]

Does that look like what you're after? If not, or you've any questions, let me know!

Upvotes: 1

spickermann
spickermann

Reputation: 106792

I would expect that something like this might work:

# in the controller (this returns a hash)
@locations = Country.joins(:user).order(:name).group(:name).count

# in your view
- @locations.each do |name, count|
  %li
    = name
    = "(#{count})" if count > 1

Upvotes: 3

Related Questions