Ruby on Rails 2 search string in Hash - ruby-on-rails

I need help with this...
I have a hash like this:
#ingredients = Hash.new
#ingredients[1] = "Biscottes Mini(recondo)"
#ingredients[2] = "Abadejo"
#ingredients[3] = "Acelga"
#ingredients[4] = "Agua de Coco"
#ingredients[5] = "Ajo"
#ingredients[6] = "Almidón de Arroz"
#ingredients[7] = "Anillos Con Avena Integral cheerios (nestle)"
#ingredients[8] = "Apio"
I need to search into that hash in order to find "Biscottes Mini(recondo)" when I write "scotte"
Some help?
Thk!

Why do you use a Hash here and not an Array? You do not seem to use other keys than integers.
Anyway, this solution works for both Array and Hashes:
search_term = 'scotte'
# you could also use find_all instead of select
search_results = #ingredients.select { |key, val| val.include?(search_term) }
puts search_results.inspect
See http://ruby-doc.org/core/classes/Enumerable.html#M001488

You can call select (or find if you only want the first match) on a hash and then pass in a block that evaluates whether to include the key/value in the result hash. The block passes the key and value as arguments, so you can evaluate whether either the key or value matches.
search_value = "scotte"
#ingredients.select { |key, value| value.include? search_value }

Related

How do I get a value from a hash that is in the array?

I have an array that contains hash in it.
[{"id"=>1353899, "client_id"=>727977, "ticket_id"=>1399613, "ticket_ticket_id"=>632355, "goods_quantity"=>143, "firm"=>nil, "cashregister"=>nil, "user_id"=>5048, "created_at"=>"2021-08-25T13:35:15", "started"=>"2021-07-05", "finished"=>"2022-07-04", "returned"=>nil, "account_summ_id"=>6481426, "account_membership_id"=>nil, "recommended"=>nil, "discount"=>"252.0", "discount_kind"=>1, "discount_comment"=>"Сотрудник", "manual_discount"=>true, "fullprice"=>"456.0", "docnumber"=>nil, "membership_summ"=>"0.0", "name"=>"SMART", "ticket_kind_id"=>1, "price"=>"204.0", "duration"=>12, "time_kind_id"=>4, "freeze_count"=>2, "freeze_days"=>61, "passes"=>nil, "tax_percent"=>"20.0", "client_surname"=>"Smetanin", "client_name"=>"Nikita", "client_phone1"=>"+372 5366 9579", "client_phone2"=>nil, "client_email1"=>"smet.n#hotmail.com", "align_to_month"=>0, "auto_continue"=>0, "stop_auto_continue"=>false, "tax_id"=>68, "day_price"=>nil, "together_with_membership"=>0, "promoaction_id"=>nil, "promocode"=>nil, "pay_schedule_option_id"=>nil, "color"=>"#FF9900", "total_limit_passes"=>0, "guest_visits"=>nil, "debt"=>"0.0", "get_next_debt"=>nil, "full_debt"=>"153.0", "debt_membership"=>0, "goods_rest"=>143, "passes_used"=>0, "guest_visits_used"=>0, "freezes_used"=>0, "freeze_days_used"=>0, "author_name"=>"Smetanin Nikita", "users"=>1, "payed"=>true, "schedule_id"=>1708, "status_freeze"=>false, "trainer_id"=>nil, "need_trainer"=>false, "duration_str"=>"12 Month", "passes_str"=>"Not limited", "next_pay"=>"2021-10-05"}]
How do I get the value of "next_pay"=>"2021-10-05"?
I've tried this, but it doesn't seem to work
#next_pay_data.each{|client_ticket|
next_pay = Luckyfit.request('GET','/client_tickets/payed_finished/' + client_ticket['id'].to_s)
client_ticket['next_pay'] = next_pay[:data]
}
If the array always has 1 hash in it, you can eassily access the hash based on the index like array[0].
So you can change your next_pay variable to return the hash inside the array like this:
next_pay = Luckyfit.request('GET','/client_tickets/payed_finished/' + client_ticket['id'].to_s)[0]
Now the next_pay variable is the hash you want it to be and from there you can access the keys like this:
client_ticket['next_pay'] = next_pay['next_pay']
And in the end your code would look like this:
#next_pay_data.each{|client_ticket|
next_pay = Luckyfit.request('GET','/client_tickets/payed_finished/' + client_ticket['id'].to_s)[0]
client_ticket['next_pay'] = next_pay['next_pay']
}
To make it a bit more readable I would suggest to change some variable names and use string interpolation like this:
#next_pay_data.each{|client_ticket|
next_pay_date = Luckyfit.request('GET',"/client_tickets/payed_finished/#{client_ticket['id']}")[0]['next_pay']
client_ticket['next_pay'] = next_pay_date
}
The below code gets all the next_pay values from the array of hash provided:
hash = [{"id"=>1353899, "client_id"=>727977, "ticket_id"=>1399613, "ticket_ticket_id"=>632355, "goods_quantity"=>143, "firm"=>nil, "cashregister"=>nil, "user_id"=>5048, "created_at"=>"2021-08-25T13:35:15", "started"=>"2021-07-05", "finished"=>"2022-07-04", "returned"=>nil, "account_summ_id"=>6481426, "account_membership_id"=>nil, "recommended"=>nil, "discount"=>"252.0", "discount_kind"=>1, "discount_comment"=>"Сотрудник", "manual_discount"=>true, "fullprice"=>"456.0", "docnumber"=>nil, "membership_summ"=>"0.0", "name"=>"SMART", "ticket_kind_id"=>1, "price"=>"204.0", "duration"=>12, "time_kind_id"=>4, "freeze_count"=>2, "freeze_days"=>61, "passes"=>nil, "tax_percent"=>"20.0", "client_surname"=>"Smetanin", "client_name"=>"Nikita", "client_phone1"=>"+372 5366 9579", "client_phone2"=>nil, "client_email1"=>"smet.n#hotmail.com", "align_to_month"=>0, "auto_continue"=>0, "stop_auto_continue"=>false, "tax_id"=>68, "day_price"=>nil, "together_with_membership"=>0, "promoaction_id"=>nil, "promocode"=>nil, "pay_schedule_option_id"=>nil, "color"=>"#FF9900", "total_limit_passes"=>0, "guest_visits"=>nil, "debt"=>"0.0", "get_next_debt"=>nil, "full_debt"=>"153.0", "debt_membership"=>0, "goods_rest"=>143, "passes_used"=>0, "guest_visits_used"=>0, "freezes_used"=>0, "freeze_days_used"=>0, "author_name"=>"Smetanin Nikita", "users"=>1, "payed"=>true, "schedule_id"=>1708, "status_freeze"=>false, "trainer_id"=>nil, "need_trainer"=>false, "duration_str"=>"12 Month", "passes_str"=>"Not limited", "next_pay"=>"2021-10-05"}]
next_pay_array = hash.map do |value|
value["next_pay"]
end
puts next_pay_array

change hash key through function call

I have a hash where the keys are country_id's and I would like to change the country_id keys to actually have the name of the country. I have a function that can do the id to name conversion but I can't figure out how to get the keys updated and mapped correctly to their current values.
Also I'm not able to use transform_keys due to the version of ruby\rails I'm on.
I don't know what country will be selected so I need a way of looping through the keys and updating them, then storing back to the hash or a new hash with the values mapped correctly.
the hash I have is called #trending_countries the keys are currently the country_id that needs to be updated and the value consists of a count for that particular country.
#trending_countries = {22=>2, 34=>3} and I would like it in the format of #trending_countries = {United States=>2, Canada=>3}
I tried doing the below in my controller
#trending_countries.each {|k, v| #trending_countries[k] = Country.get_country_name(k)}
the function doing the id to name conversion is in a separate model called Country.
# returns the country name when a country id is given.
def self.get_country_name(country_id)
country = self.find_by(id: country_id)
return country.name
end
One way to do it is the following:
old_hash.map { |key, value| [Country.get_country_name(key), value] }.to_h
old_hash = { 62=>:wee, 12=>:big, 8=>:medium }
country_id_to_name = { 62=>"Monaco", 8=>"France", 12=>"China" }
old_hash.each_with_object({}) { |(k,v),h| h[country_id_to_name[k]] = v }
#=> {"Monaco"=>:wee, "China"=>:big, "France"=>:medium}

how to check if a certain key-value pair exists in array of hashes as json in ruby on rails

I have an array of hashes as json, so how to check my array of hashes contains a hash with a given key-value pair.
This is my json
[{"question"=>"0a2a3452", "answer"=>"bull"}, {"question"=>"58deacf9", "answer"=>"bullafolo"}, {"question"=>"32c53e5f", "answer"=>"curosit"}, {"question"=>"b5546bcf", "answer"=>""}, {"question"=>"0f0b314", "answer"=>""}]
I tried looping through the json array, but this is tedious, as I need to check that if that json has that hash with a given key-value pair
It's a questionnaire form, in which I have to perform an update on answers
if !#client_find.nil?
#client_find.questionnaire
params[:commit].each do |key, value|
#json=[]
#json = #client_find.questionnaire
if !value.empty? && #json.include?(key)
puts "blunderc "+ value.inspect
#new_append = Hash.new
#new_append[:question] = key
#new_append[:answer]= value
#json << #new_append
end
if !key.empty? && !value.empty?
#logic
#json.each do |u|
if (u.key? key)
puts "bothu "+ u[key].inspect
u[key] = value
end
end
end
end
Array#any? iterates through the array. In each iteration I check wether the current hash has the searched question key or not. If a hash is found Array#any? returns true otherwise false.
array = [{"question"=>"0a2a3452", "answer"=>"bull"}, {"question"=>"58deacf9", "answer"=>"bullafolo"}, {"question"=>"32c53e5f", "answer"=>"curosit"}, {"question"=>"b5546bcf", "answer"=>""}, {"question"=>"0f0b314", "answer"=>""}]
search_for_key = '0a2a3452'
array.any?{|hash| hash['question'] == search_for_key}
I'll assume that you want to check the existence of a hash which has the key/value pair "quesetion" => "some-value".
Here's how you can do it:
array.any? { |item| item['question'] == 'some-question-id' }
Considering your are checking for a particular key exists or not
#json.any? {|obj| obj.key?(your_particular_key)
You can filter the array using Enumerable#select to get only the hashes that contains the desired key.
filtered = my_hash.select { |item| item['desired_key'] }
That's possible because nil is falsey. If you input is a raw JSON you'll need to parse it to a Ruby hash using JSON#parse or any other equivalent method.
filtered will give you all the hashes that contain the desired_key.
Is that what you want ?
Btw guitarman's answer is way better !
questions = [{"question"=>"0a2a3452", "answer"=>"bull"}, {"question"=>"58deacf9", "answer"=>"bullafolo"}, {"question"=>"32c53e5f", "answer"=>"curosit"}, {"question"=>"b5546bcf", "answer"=>""}, {"question"=>"0f0b314", "answer"=>""}]
result = questions.find { |question| question['question'] == "Bonour" }
if result.nil?
puts "Not found"
else
puts "#{result['question']} #{result['answer']}"
end

Storing and retrieving session objects

I'm storing an object in hash which is in session object like this :
hash_key = ImportantData.new
hash_key.test_id = params[:test_id]
hash_key.user_id = params[:user_id]
session[:important_data] ||= {}
session[:important_data][hash_key] = nil
And then I print this map session[:important_data][hash_key] in my other controller and try to check whether the object is in there or not like this :
hash_key = ImportantData.new
hash_key.schedule_id = #test.id
hash_key.user_id = #user.id
in_hash = session[:important_data].has_key?(hash_key) unless session[:important_data].nil?
in_hash is always false to me, what am I doing wrong? and is there a better way to do this?
In Ruby, hash keys work by equality. You can store and retrieve a value in a hash as long as the key you're using is equal to the key that's stored.
For instance:
hsh = { 'hello' => 'world' }
p hsh['hello'] #=> "world"
'hello'.eql? 'hello' #=> true
You can retrieve the value because the same value string is always eql? in Ruby.
This is not the case for most objects:
class Example; end
object1 = Example.new
object2 = Example.new
object1.eql? object2 #=> false
Therefore, the key that you use to store in the hash must be eql? to the one that you're using to retrieve. eql? is equivalent to == and equal?.
You're creating two instances of ImportantData, which will not be equal to each other. It looks like you can accomplish what you want with a single hash key:
hash_value = ImportantData.new
hash_value.test_id = params[:test_id]
hash_value.user_id = params[:user_id]
session[:important_data] ||= hash_value
puts session[:important_data].class.name #=> ImportantData
session[:important_data].test_id #=> puts out value of test_id
I think you should assign it like this
session[:important_data][:hash_key] = hash_key
and access it
session[:important_data][:hash_key]

returning an array that contains an array and hash in ruby method?

HI
is it possible to return an array that contains an array and hash from a method in ruby?
i.e
def something
array_new = [another_thing, another_thing_2]
hash_map = get_hash()
return [array_new, hash_map]
end
and to retrieve the array:
some_array, some_hash = something()
thanks
Sure, that's perfectly possible and works exactly as in your example.
You will only ever be able to return one thing. What you are returning there is an array containing an array and a hash.
Ruby methods can be treated as if they return multiple values so you can collect the items in an array or return them as separate objects.
def something
array_new = Array.new
hash_new = Hash.new
return array_new, hash_new
end
a, b = something
a.class # Array
b.class # Hash
c = something
c.class # Array

Resources