Where is the method for the array

I'm pretty much trying to mimic a class method where

, but instead on an instance, that instance is 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 an object @joe

.

How should I write this?

+3


source to share


5 answers


As I understand it, the task you want to define Array#where

. Here you are:

class Arraydef where hashreturn nil unless hash.is_a? Hash # one might throw ArgumentError hereself.select do |e| 
▷       e.is_a?(Hash) && hash.all? { |k, v| e.key?[k] && e[k] == v }endendend  
#⇒ :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 function to distinguish between values nil

and missing keys. Credits to @CarySwoveland.

+5


source


You can use Enumerable # find to get the first element that matches:

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

      



or List # find_all to retrieve all elements that match:

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

      

+3


source


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

      

or

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

      

or

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

      

Using the method:

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

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

      

0


source


This is slightly different from Rails' where

, more like find_by

: where

returns a relation, a collection of instances. In fact, the implementations of both are about the same and use different methods 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 fulfilling Enumerable#all?

the hash condition.

0


source


If you're talking about a real array of hashes and an inactive entry:

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

      

0


source







All Articles