How to Search Within an Array of Hashes by Hash Values in Ruby

How do I search within an array of hashes by hash values in ruby?

You're looking for Enumerable#select (also called find_all):

@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
# { "age" => 50, "father" => "Batman" } ]

Per the documentation, it "returns an array containing all elements of [the enumerable, in this case @fathers] for which block is not false."

How to search for a hash key value in an array of hashes

find returns a hash in your case, just pass the key :place to get the value:

hash = array.find {|x| x[:name] == "John"}
return if hash.nil?
hash[:place]

Regarding the query about mixed values, I just tried it in IRB and it worked fine.

2.7.0 :014 > array = [
2.7.0 :015 > {:name => "Bob" , :age => 27 , :place => "A"} ,
2.7.0 :016 > {:name => "John" , :age => 50 , :place => "B"} ,
2.7.0 :017 > {:name => "Alex" , :age => 80 , :place => "C"}
2.7.0 :018 > ]
2.7.0 :019 > array.find {|x| x[:name] == "John"}
=> {:name=>"John", :age=>50, :place=>"B"}

Filter an array of hashes to keep only those elements whose hashes contain a key contained in an array?

Try the below with Array select:

select will return an array containing elements which match the condition provided on the block.

Hope the hash on every index of the array will include only one key

 @arr_of_h.select{ |element| arr.include?(element.keys.first.to_s) }

EDIT #1

To find the record which at least has one key contained in an array

We can achieve it through Array select and Array any?

 @arr_of_h.select{ |element| element.keys.any? {|element| arr.include?(element.to_s) }}

Get position of hash in array of hashes

An array of hashes, each hash representing a student:

students = [
{'score' => 10, 'name' => 'Bob'},
{'score' => 20, 'name' => 'Tom'},
{'score' => 60, 'name' => 'Pete'},
{'score' => 50, 'name' => 'Ane'}
]

best_student = students.max_by{|student| student['score']}

After you get the student with the highest score, you can find his position in the array with the #index method:

index = students.index(best_student)
#=>2

So you can do this:

puts "The best student is #{best_student['name']}, number #{index+1}, with a score of #{best_student['score']}."
#=>The best student is Pete, number 3, with a score of 60.

On a side note, the position of a student in an array in your app shouldn't represent info about the student, that info should be saved as an additional attribute in the hash. Imagine if you sorted the array for some reason, that valuable data would be lost. I think you would be much better off if you made an array like this:

students = [
{'id' => 1, 'score' => 10, 'name' => 'Bob'},
...
]

Collect specific values from an array of hashes

A Hash is a dictionary-like collection of unique keys and their values. Also called associative arrays, they are similar to Arrays, but where an Array uses integers as its index, a Hash allows you to use any object type.

Of course, a value can be any object - string, method, nil, number, object. So, only after create, we can know that is saved in our hash. For this reason when trying to get all key:

data.keys # => ["etag", "items"]

There is no any nested key. So finding value by missing key return nil.

To select all videoId you must do something like this:

data["items"].map { |item| item["snippet"]["resourceId"]["videoId"] }.compact

Also, you can update Hash class as there:

class Hash
def deep_find(key, object=self, found=nil)
if object.respond_to?(:key?) && object.key?(key)
return object[key]
elsif object.is_a? Enumerable
object.find { |*a| found = deep_find(key, a.last) }
return found
end
end
end

And then run

data["items"].map { |item| item.deep_find('videoId') }

That method avoids the error when the json will have a variable structure.

How do I search an array of hashes based on multiple keys in Rails Postgres?

This is really just a classic example of shooting yourself in the foot with bad database modeling.

Postgres arrays are a good tool for really specialized tasks where you have an array of simple scalar values such as integers or strings. They are not a good idea if you want to store hashes. If you shove a Ruby hash inside of an array column you get an non-queryable mess.

The JSON/JSONB type can store more complex structures like an array of objects and is a valid choice if the data defies any attempt to confirm to a schema. While you can query an array of objects with the includes operator:

SELECT *
FROM "drinkers"
WHERE habits @> '[{"year": 2020}]'

You are really not doing yourself any favors here if the data is structured. Once you step up the complexity the queries will be hideous and you won't have any indices that will speed them up either.

Instead you want to just face the facts that relational databases are tabular and the way to model data in a relational database is - you guessed it - tables.

class Drinker < ApplicationRecord
has_many :habits
end

class Habit < ApplicationRecord
belongs_to :drinker
end

Drinker.joins(:habits)
.where(habits: { year: 2020 })

TLDR; array, JSON/JSONB and hstore are decent tools for really specialized jobs. But should never be your first choice for anything.

Get a value from an array of hashes in ruby

The select statement will return all the hashes with the key 13.

If you already know which hash has the key then the below code will give u the answer.

ary[1][13]

However if you are not sure which of your hashes in the array has the value, then you could do the following:

values = ary.map{|h| h[13]}.compact

Values will have the value of key 13 from all the hashes which has the key 13.

Ruby easy search for key-value pair in an array of hashes

ary = [
{"href"=>"https://company.campfirenow.com", "name"=>"Company", "id"=>123456789, "product"=>"campfire"},
{"href"=>"https://basecamp.com/123456789/api/v1", "name"=>"Company", "id"=>123456789, "product"=>"bcx"},
{"href"=>"https://company.highrisehq.com", "name"=>"Company", "id"=>123456789, "product"=>"highrise"}
]

p ary.find { |h| h['product'] == 'bcx' }['href']
# => "https://basecamp.com/123456789/api/v1"

Note that this only works if the element exists. Otherwise you will be calling the subscription operator [] on nil, which will raise an exception, so you might want to check for that first:

if h = ary.find { |h| h['product'] == 'bcx' }
p h['href']
else
puts 'Not found!'
end

If you need to perform that operation multiple times, you should build yourself a data structure for faster lookup:

href_by_product = Hash[ary.map { |h| h.values_at('product', 'href') }]
p href_by_product['campfire'] # => "https://company.campfirenow.com"
p href_by_product['bcx'] # => "https://basecamp.com/123456789/api/v1"

Ruby problem with returning hash value from an array of hashes

After reading your edited question, I see that there are a few conditions that weren't met with previous answers. I also see the main flaw in your code. Let's start with the flaw:

Your code seems a little overly complicated but it should work just fine if you make this one small change to the 5th line of the following section;

def find_favorite(array_of_hash_objects)
array_of_hash_objects.each do | hash |
hash.each do |key, val|
if key == :is_my_favorite? && val == true
return hash
end
end
end
return nil
end

Notice that I prepended the line with return. Your problem was that you were iterating through the array just fine but there was no container or method being initiated in order to store or return those results. Your second to last line was telling the method to return nil no matter what the results of the iteration were.


Now for my proposed solution:

I see now that your desired output should either be the single hash containing the true value or should be nil as opposed to the arrays resulting from the solutions mentioned above. I would probably do something like this;

def find_favorite(input)
output = nil
input.each{|h| h[:is_my_favorite?] ? output = h : nil}
output
end

arr_1 = [{ name: 'Ruby', is_my_favorite?: true }, { name: 'JavaScript', is_my_favorite?: false }, { name: 'HTML', is_my_favorite?: false }]
arr_2 = [{ name: 'Ruby', is_my_favorite?: false }, { name: 'JavaScript', is_my_favorite?: false }, { name: 'HTML', is_my_favorite?: false }]


find_favorite(arr_1) #=> {:name=>"Ruby", :is_my_favorite?=>true}
find_favorite(arr_2) #=> nil

Within the method definition, a container (output) is first defined with a default value of nil. We then iterate through the array and fill output with the hash containing a true value. Otherwise output returns the default value.

NOTE: You could optionally delete == true ? from the block but seeing as how I don't know how the original array is being created, I prefer to leave it in there to expressly communicate exactly what I'm looking for in a very human readable way. That's just my personal preference.

How to iterate over an array of hashes in Ruby and return all of the values of a specific key in a string

You can use Enumerable#map for this:

p foods.map { |f| f[:name] }

The code you tried to use did not produce any output or create any objects, and it was not necessary to use a second loop to access a single element of a hash.



Related Topics



Leave a reply



Submit