Array help needed

Hello, sorry if this question is stupid but I can't find a solution after several readings about Arrays

Array 'a' contains several objets (ruby classes instances), each instance have an id property

I need a clean solution to return true if array 'a' contains an instance with id foo without iterating the whole array.

Example

def add_user(user)
   unless users.include?(user.id)
     users << user
   end
end

users.include? statement is wrong because we compare id's with objects.
Which is the right way to do it ?

Thanks

Hello, sorry if this question is stupid but I can't find a solution
after several readings about Arrays

Array 'a' contains several objets (ruby classes instances), each
instance have an id property

I need a clean solution to return true if array 'a' contains an instance
with id foo without iterating the whole array.

Example

def add_user(user)

- unless users.include?(user.id)
+ unless users.any? {|u| user.id == u.id }

···

On Tue, Feb 26, 2008 at 3:20 PM, Zouplaz <user@domain.invalid> wrote:

     users << user
   end
end

Read up on the Enumerable module.
module Enumerable - RDoc Documentation.

You have a couple of options. The simplest code-wise is to use find:

def add_user(user)
  unless users.find { |u| u.id == user.id }
    users << user
  end
end

Potentially marginally more efficient is #map and then calling
#include? on the result

def add_user(user)
  unless users.map { |u| u.id }.include?(user.id)
    users << user
  end
end

Christopher

···

On 2/26/08, Zouplaz <user@domain.invalid> wrote:

Hello, sorry if this question is stupid but I can't find a solution
after several readings about Arrays

Array 'a' contains several objets (ruby classes instances), each
instance have an id property

I need a clean solution to return true if array 'a' contains an instance
with id foo without iterating the whole array.

Example

def add_user(user)
   unless users.include?(user.id)
     users << user
   end
end

users.include? statement is wrong because we compare id's with objects.
Which is the right way to do it ?

If you can't do this

def add_user(user)
  unless users.include?(user) # just check the user instead of the id
    users << user
  end
end

then I'd also recommend Jano's solution.

Regards,
Craig

···

On Tue, Feb 26, 2008 at 9:36 AM, Jano Svitok <jan.svitok@gmail.com> wrote:

On Tue, Feb 26, 2008 at 3:20 PM, Zouplaz <user@domain.invalid> wrote:
> Hello, sorry if this question is stupid but I can't find a solution
> after several readings about Arrays
>
> Array 'a' contains several objets (ruby classes instances), each
> instance have an id property
>
>
> I need a clean solution to return true if array 'a' contains an
instance
> with id foo without iterating the whole array.
>
> Example
>
> def add_user(user)
- unless users.include?(user.id)
+ unless users.any? {|u| user.id == u.id }
> users << user
> end
> end

For a more efficient solution use a Hash:

def add_user(user)
  @users[user.id] ||= user
end

def users
  @users.values
end

Kind regards

robert

···

2008/2/26, Jano Svitok <jan.svitok@gmail.com>:

On Tue, Feb 26, 2008 at 3:20 PM, Zouplaz <user@domain.invalid> wrote:
> Hello, sorry if this question is stupid but I can't find a solution
> after several readings about Arrays
>
> Array 'a' contains several objets (ruby classes instances), each
> instance have an id property
>
>
> I need a clean solution to return true if array 'a' contains an instance
> with id foo without iterating the whole array.
>
> Example
>
> def add_user(user)
- unless users.include?(user.id)

+ unless users.any? {|u| user.id == u.id }
> users << user
> end
> end

--
use.inject do |as, often| as.you_can - without end

Additionally, if a unique user always has the same id (for instance,
they're defined in a database and the id is the primary key), then you
can override #== in your class to compare ids to determine equality.
Then you can just call #include? with the user directly:

def add_user(user)
  unless users.include?(user)
    users << user
  end
end

This is almost definitely the most efficient solution, but it does
require you to modify your class.

Best,
Christopher

···

On 2/26/08, Christopher Swasey <christopher.swasey@gmail.com> wrote:

On 2/26/08, Zouplaz <user@domain.invalid> wrote:
> Hello, sorry if this question is stupid but I can't find a solution
> after several readings about Arrays
>
> Array 'a' contains several objets (ruby classes instances), each
> instance have an id property
>
>
> I need a clean solution to return true if array 'a' contains an instance
> with id foo without iterating the whole array.
>
> Example
>
> def add_user(user)
> unless users.include?(user.id)
> users << user
> end
> end
>
> users.include? statement is wrong because we compare id's with objects.
> Which is the right way to do it ?

Read up on the Enumerable module.
http://www.ruby-doc.org/core/classes/Enumerable.html#M003153\.

You have a couple of options. The simplest code-wise is to use find:

def add_user(user)
  unless users.find { |u| u.id == user.id }
    users << user
  end
end

Potentially marginally more efficient is #map and then calling
#include? on the result

def add_user(user)
  unless users.map { |u| u.id }.include?(user.id)
    users << user
  end
end

Christopher

Fine ! This is was I was looking for.

Thanks to people who answered...

···

le 26/02/2008 15:36, Jano Svitok nous a dit:

def add_user(user)

- unless users.include?(user.id)
+ unless users.any? {|u| user.id == u.id }

     users << user
   end
end