Reputation: 7359
I would just like to return true, if my Array of Contact(s) (model) contains a Contact with id equal to some value. For example:
@contacts = Contact.all
@someval = "alskjdf"
find_val(@contacts, @someval)
def find_val(contacts, val)
@contact.each do |c|
if c.id == val
return true
end
end
return false
end
I have to do this repeatedly in my app (at most about 100 times for this particular actions), in order to exclude some data from an external API that has a list of contacts. Is this going to be too expensive?
I thought I might be able to do something faster, similar to ActiveRecord find on the array after it's been pulled down from the db, but can't figure that out. Would it be too expensive to call ActiveRecord like this?
Contacts.find_by_id(@someval)
The above line would have to be called hundreds of times... I figure iterating through the array would be less expensive. Thanks!
Upvotes: 1
Views: 532
Reputation: 5167
One way to reduce the amount of code you have to write to search the array is to open the array class and make a custom instance method:
class Array
def haz_value?(someval)
if self.first.respond_to? :id
self.select { |contact| contact.id == someval }.length > 0
else
false
end
end
end
Then, you can call @contacts.haz_value? @someval
. In terms of efficiency, I haven't done a comparison, but both ways use Array's built-in iterators. It would probably be faster to create a stored procedure in your database and call it through ActiveRecord, here is how you can do that.
Upvotes: 1
Reputation: 18550
The best approach would be to index the contacts in a hash, using the contact id as the key after you retrieve them all from the db:
contacts = Contact.all.inject({}) {|hash, contact| hash[contact.id] = contact; hash }
Then you can easily get a contact with contact[id]
in a performant way.
Upvotes: 2