Reputation: 43
I am pretty much trying to mimic the class method of where
, but instead on an instance, this instance being an array of hashes. For example: this exists as a class method Class.where(:name => "Joe")
, so I want to be able to do this:
@joe = {:name => "Joe", :title => "Mr.", :job => "Accountant"}
@kelly = {:name => "Kelly", :title => "Ms.", :job => "Auditor"}
@people = [@joe, @kelly]
and call this:
@people.where(:name => 'Joe')
which should return the @joe
object.
How should I write this?
Upvotes: 3
Views: 437
Reputation: 3819
You can use Enumerable#find to retrieve the first element that matches:
@people.find { |p| p[:name] == 'Joe' }
or Enumerable#find_all to retrieve all elements that match:
@people.find_all { |p| p[:name] == 'Joe' }
Upvotes: 3
Reputation: 121000
As I understood the task, you want to have Array#where
defined. Here you go:
▶ class Array
▷ def where hash
▷ return nil unless hash.is_a? Hash # one might throw ArgumentError here
▷ self.select do |e|
▷ e.is_a?(Hash) && hash.all? { |k, v| e.key?[k] && e[k] == v }
▷ end
▷ end
▷ end
#⇒ :where
▶ @people.where(:name => 'Joe')
#⇒ [
# [0] {
# :job => "Accountant",
# :name => "Joe",
# :title => "Mr."
# }
# ]
▶ @people.where(:name => 'Joe', :job => 'Accountant')
#⇒ [
# [0] {
# :job => "Accountant",
# :name => "Joe",
# :title => "Mr."
# }
# ]
▶ @people.where(:name => 'Joe', :job => 'NotAccountant')
#⇒ []
Hope it helps.
UPD Slightly updated the function to distinguish nil
values and absent keys. Credits to @CarySwoveland.
Upvotes: 5
Reputation: 45941
@people.find{|p| p[:name] =='Joe'}
or
@people.find(:name => 'Joe').first
or
@people.select{|p| p[:name ]== 'Joe'}.first
With a method:
def find_user params
@people.find(params).first
end
find_user name:'Joe'
=> {:name=>"Joe", :title=>"Mr.", :job=>"Accountant"}
Upvotes: 0
Reputation: 26912
If you are talking about an actual array of hashes and not active record:
@some_array.select {|item| item["search_key"] = 'search val' }
Upvotes: 0
Reputation: 9495
It's a bit different to Rails' where
, more like find_by
: where
returns a relation, a collection of instances. Actually, the implementations of both are about the same and use different methods of Enumerable
:
@people.select { |h| h[:name] == 'Joe' } # where-like
@people.find { |h| h[:name] == 'Joe' } # find_by-like
You can generalize it at any time, by running Enumerable#all?
on conditions hash.
Upvotes: 0