数组的where方法

where method for Array

我非常想模仿 where 的 class 方法,但不是在一个实例上,这个实例是一个哈希数组。例如:这作为 class 方法 Class.where(:name => "Joe") 存在,所以我希望能够这样做:

@joe = {:name => "Joe", :title => "Mr.", :job => "Accountant"}
@kelly = {:name => "Kelly", :title => "Ms.", :job => "Auditor"}
@people = [@joe, @kelly]

并称之为:

@people.where(:name => 'Joe')

哪个应该 return @joe 对象。

这个应该怎么写?

@people.find{|p| p[:name] =='Joe'}

@people.find(:name => 'Joe').first

@people.select{|p| p[:name ]== 'Joe'}.first

使用方法:

def find_user params
  @people.find(params).first
end

find_user name:'Joe'
=> {:name=>"Joe", :title=>"Mr.", :job=>"Accountant"}

您可以使用 Enumerable#find 检索匹配的第一个元素:

@people.find     { |p| p[:name] == 'Joe' }

Enumerable#find_all 检索所有匹配的元素:

@people.find_all { |p| p[:name] == 'Joe' }

它与 Rails' where 有点不同,更像是 find_bywhere returns 一个关系,一个实例的集合。实际上,两者的实现大致相同,使用的方法不同 Enumerable:

@people.select { |h| h[:name] == 'Joe' } # where-like
@people.find   { |h| h[:name] == 'Joe' } # find_by-like

您可以随时通过 运行 Enumerable#all? 对条件哈希进行概括。

根据我对任务的理解,您希望定义 Array#where。给你:

▶ 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')
#⇒ []

希望对您有所帮助。

UPD 稍微更新了区分 nil 值和缺失键的功能。感谢@CarySwoveland。

如果您谈论的是实际的哈希数组而不是活动记录:

@some_array.select {|item| item["search_key"] = 'search val' }