Texas
Texas

Reputation: 913

Equivalent of Array#Uniq in Ruby1.8.7

I posted a question earlier - Issues with DISTINCT when used in conjunction with ORDER to which I received a great answer which worked locally on my machine. However, when I pushed it to the server the code didn't do anything to the results... I have since contacted our host provider and discovered that the version of Ruby on the server is 1.8.7

With this in mind, is anyone able to tell me how I can do the equivalent of

@unique_results = @filtered_names.uniq { |result| result.athlete_id }

in a way that will run on our server?

As it stands @unique_results is identical to @filtered_names and the repeat names (as described in the original post) remain in the output.

Thanks for your time

Upvotes: 1

Views: 223

Answers (3)

Alex D
Alex D

Reputation: 30445

One step toward mastering Ruby is to learn to extend the core classes when you need some functionality which is sufficiently general to make sense as a "core" operation. If your programming background is in less dynamic languages, this will take some getting used to. In this case I would add something like this:

require 'set'
module Enumerable
  def uniq(&b)
    if block_given?
      self.map(&b).to_set.to_a
    else
      self.to_set.to_a
    end
  end
end

It won't be as efficient as the uniq built in to Ruby 1.9, but it's still O(n).

Adding this to Enumerable means you can use it on things other than Arrays. If a certain enumerable class defines a more efficient version, this will not override it -- the Ruby method lookup algorithm checks first for methods defined directly in a class, before looking for methods defined in included modules.

If you use Ruby 1.8 a lot, you can add this to a file of your own personal core extensions, and use it on future projects. If you are interested, you can see some my personal core extensions at https://github.com/alexdowad/showcase/blob/master/ruby-core/collections.rb (these are for Ruby 1.9).

Upvotes: 2

mu is too short
mu is too short

Reputation: 434665

You could add Marc-André Lafortune's backports to your gem list, that includes the block for of uniq and a ton of other stuff. You could also cherry pick the updated uniq out of backports if you just want that one piece.

Upvotes: 2

KL-7
KL-7

Reputation: 47618

If you're using Rails 3.* you can use Array#uniq_by.

Otherwise you can either look into its implementation (it's pretty straightforward, click Show source on the page to see it) and do smth similar or just reopen Array class and add that uniq_by method yourself.

Upvotes: 2

Related Questions