0

i was wondering if someone could help me with returning the count for duplicates?

ive been reading How to count duplicates in Ruby Arrays

and that's very close to what i want. however the code is quite difficult to understand.

for example if i had an array...

[#<Badge id: 1, name: "justice">, #<Badge id: 9, name: "resonator">, #<Badge id: 9, name: "resonator"> ]

i would want a function that would return some indication the user has 2 of the badges 'resonator'.

im trying to create a badge system similar to how stackoverflow's work. some badges can be awarded multiple times, and if they are, i want some form of count on the badges. however ive been having much trouble thinking how to do this. i think first i need to count the amount of duplicates.

ultimately in the end of my code, im just rendering the badges name like so

<li>
    <%= badge_item.name %>
</li>

so that it would show something like...

badges:

justice

resonator x2

how can i do this? is removing duplicates the right way to go? help would be appreciated. thank you!

Community
  • 1
  • 1
Sasha
  • 3,281
  • 7
  • 34
  • 52

3 Answers3

2

You probably want to do something like this:

Controller:

@badge_names_with_counts = user.badges.count(group: :name)

View:

<% @badge_names_with_counts.each do |badge_name_with_count| %>
  <%= badge_name_with_count.name %> x<%= badge_name_with_count.count %>
<% end %>
Chris Mohr
  • 3,639
  • 1
  • 13
  • 9
1

Well perhaps there is a more fancy ruby way to do it but for a start you can do something like:

badges = [#<Badge id: 1, name: "justice">, #<Badge id: 9, name: "resonator">, #<Badge id: 9, name: "resonator"> ]
counts = {}

badges.each do {|badge|
  #depends on you whether you want to count by id or name
  counts[badge.id] ||= 0
  counts[badge.id] += 1
}

And then you can safely make your array unique and display the counts like this:

badges.uniq!

badges.each do |badge|
  puts badge.name
  puts counts[badge.id]
end

But I'm pretty sure there is a better iterator in ruby for making the counts. Perhaps that inject or reduce.

Renra
  • 5,561
  • 3
  • 15
  • 17
0

for some reason, the method .count wasn't working. maybe i wasn't pulling from the db or something? so instead i did in my controller..

@badge_names_with_counts = @user.badges.group_by(&:name)

which returns a hash, and i looped through it by...

<% if @badge_names_with_counts.any? %>
    <ol class='badges'>
    <% @badge_names_with_counts.each do |key, value| %>
        <% if value.count > 1 %>
            <li><%= key %> x <%= value.count %></li><br/>
        <% else %>
            <li><%= key %></li><br/>
        <% end %>
    <% end %>
    </ol>
<% end %>
Sasha
  • 3,281
  • 7
  • 34
  • 52