Christian Fazzini
Christian Fazzini

Reputation: 19713

How do I get unique elements in this array?

Using Mongoid. Unfortunately, Mongoid does not allow for selecting unique / distinct! Have gotten these results. As you can see, there are 7 results. If you look carefully (at user_id), there are only 2 users.

[
  #<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
  #<Activity _id: 4cea6c3072357e00fa000116, created_at: 2010-11-22 13:12:16 UTC, updated_at: 2010-11-22 13:12:16 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
  #<Activity _id: 4cea6bdd72357e00fa00010d, created_at: 2010-11-22 13:10:53 UTC, updated_at: 2010-11-22 13:10:53 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
  #<Activity _id: 4cea46df72357e00fa0000a4, created_at: 2010-11-22 10:33:03 UTC, updated_at: 2010-11-22 10:33:03 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
  #<Activity _id: 4cea40c572357e00fa00006f, created_at: 2010-11-22 10:07:01 UTC, updated_at: 2010-11-22 10:07:01 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>, 
  #<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>, 
  #<Activity _id: 4cea344a72357e00fa00003f, created_at: 2010-11-22 09:13:46 UTC, updated_at: 2010-11-22 09:13:46 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea306c72357e00fa000031')>
] 

I was looking at this, and was thinking I could do something similar so that my array would now look like this:

[
  #<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
  #<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>
]

I'm not concerned which combination of results are extracted. As long as I have unique user_id's in the result set. Anyone know how this can be achieved?

Upvotes: 76

Views: 119965

Answers (6)

ajmartin
ajmartin

Reputation: 2409

This should work for you:

Consider Table1 has a column by the name of activity which may have the same value in more than one record. This is how you will extract ONLY the unique entries of activity field within Table1.

#An array of multiple data entries
@table1 = Table1.find(:all) 

#extracts **activity** for each entry in the array @table1, and returns only the ones which are unique 

@unique_activities = @table1.map{|t| t.activity}.uniq 

Upvotes: 16

xiy
xiy

Reputation: 878

For those hitting this up in the future, you can now use the Mongoid::Criteria#distinct method from Origin to select only distinct values from the database:

# Requires a Mongoid::Criteria
Attendees.all.distinct(:user_id)

http://mongoid.org/en/mongoid/docs/querying.html (v3.1.0)

Upvotes: 11

Christian Fazzini
Christian Fazzini

Reputation: 19713

Errr, it's a bit messy in the view. But I think I've gotten it to work with group (http://mongoid.org/docs/querying/)

Controller

@event_attendees = Activity.only(:user_id).where(:action => 'Attend').order_by(:created_at.desc).group

View

<% @event_attendees.each do |event_attendee| %>    
  <%= event_attendee['group'].first.user.first_name %>
<% end %>

Upvotes: 0

the Tin Man
the Tin Man

Reputation: 160551

Instead of using an Array, consider using either a Hash or a Set.

Sets behave similar to an Array, only they contain unique values only, and, under the covers, are built on Hashes. Sets don't retain the order that items are put into them unlike Arrays. Hashes don't retain the order either but can be accessed via a key so you don't have to traverse the hash to find a particular item.

I favor using Hashes. In your application the user_id could be the key and the value would be the entire object. That will automatically remove any duplicates from the hash.

Or, only extract unique values from the database, like John Ballinger suggested.

Upvotes: 2

John Ballinger
John Ballinger

Reputation: 7540

Have you looked at this page?

http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct

That might save you some time?

eg db.addresses.distinct("zip-code");

Upvotes: 8

Peter
Peter

Reputation: 132197

You can just use the method uniq. Assuming your array is ary, call:

ary.uniq{|x| x.user_id}

and this will return a set with unique user_ids.

Upvotes: 199

Related Questions