Method that outputs hash value [closed] - ruby

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Say I have two hashes that share one key (for example "foo") but different values. Now I want to create a method with one attribute that puts out the value of the key depending on which hash I chose as attribute. How do I do that?
I have tried:
def put_hash(hash)
puts hash("foo")
end
but when I call this function with a hash it gives me the error below:
undefined method `hash' for main:Object (NoMethodError)

You need to access the value with []:
puts hash["foo"]
Otherwise Ruby thinks you're trying to invoke a method with (), and you're seeing an error because there is no method called hash in that scope.

Have you tried:
def put_hash(hash)
puts hash["foo"]
end
Or better yet:
def put_hash(hash)
puts hash[:foo]
end
Ruby stores the values in a hash like this:
{ :foo => "bar" }
or
{ "foo" => "bar" }
Depending if you use a Symbol or a String
To access them you need to call the [] method in the Hash class
The Ruby Docs are always a good starting point.

Write it as
def put_hash(hash)
puts hash["foo"]
end
h1 = { "foo" => 1 }
h2 = { "foo" => 2 }
put_hash(h2) # => 2
Look here Hash#[]
Element Reference—Retrieves the value object corresponding to the key object

Related

TypeError Parsing Ruby Array of Hashes [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I have an Array of Ruby Hashes that I'm trying to iterate so that I can parse values by key.
forms = {"forms":[{"id":123,"name":"John","created_at":"2021-11-23T21:41:17.000Z"},{"id":456,"name":"Joe","created_at":"2021-11-21T05:17:44.000Z"}]}
forms.each do |form|
puts form ## {:id=>123, :name=>"John", :created_at=>"2021-11-23T21:41:17.000Z"}
puts form["id"]
end
This yields the following error:
main.rb:4:in `[]': no implicit conversion of String into Integer (TypeError)
I'm admittedly a big Ruby noob, but can't figure this out. I've also tried puts form[:id] and puts form[":id"] to no avail.
Note: I don't have any control over the Array of Hashes that's being assigned to the forms variable. It's what I get back from an external API call.
Your forms is a Hash. If you do each on Hash it passes to the block each key & value pair.
forms.each do |key, value|
p key # => :forms
p value # => [{....}]
p value.map { |v| v[:id] }
end
There's also this, in case the forms always has the forms key (doesn't change)
forms[:forms].map { |v| v[:id] }

How to get args when call function with square brackets in the Ruby [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am the beginner of Ruby.
I get one problem when I read the Ruby code.
There have one function with square-brackets.
How can I get the args from that function?
Here is the Class
class Student
class << self
def count
end
end
end
Here is the function request.
Student.count["Jack"]
Square brackets have no special meaning in Ruby. It is rather a method #[] called on the receiver.
Amongst many others, this method is noticeably declared by Array, Hash and Proc. Because of the parameter passed to #[], which is "Jack" string, it is most likely either Hash or Proc.
That said, it depends on what is returned by Student::count.
Hash example
def count
{"Jack" => 1, "Mary" => 2}
end
count["Jack"]
#⇒ 1
Proc example
def count
->(name) { "Hi, #{name}!" }
end
count["Jack"]
#⇒ "Hi, Jack!"

What is the correct way to use variable symbols in a hash? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have two arrays:
people_keys = ['id', 'name', 'email']
people_values = [[1, 'Tarzan', 'tarzan#jungle.com'],
[2, 'Jane', 'jane#jungle.com' ]]
and I want to make an array of people:
people = []
people_values.each do |person_values|
person = {}
person_values.each_with_index do |person_value, index|
person[people_keys[index]] = person_value
end
people.push( person )
end
This gives me the following result:
people # => [{"id"=>1, "name"=>"Tarzan", "email"=>"tarzan#jungle.com"},
# {"id"=>2, "name"=>"Jane", "email"=>"jane#jungle.com" }]
I want to make id, name and email symbols instead of strings,
so I came up with the following:
I replaced
person[people_keys[index]] = person_value
with
person[:"#{people_keys[index]}"] = person_value
This gives me the following result:
people # => [{:id=>1, :name=>"Tarzan", :email=>"tarzan#jungle.com"},
# {:id=>2, :name=>"Jane", :email=>"jane#jungle.com" }]
This works just fine but seems like it could be done better/cleaner,
but I am unable to find a better solution.
I'd like to know if there is in fact a better solution for this problem.
Ruby's String class has a to_sym method:
Returns the Symbol corresponding to str, creating the symbol if it did not previously exist.
You could do something like this:
people_values.map { |person| people_keys.map(&:to_sym).zip(person).to_h }

Learn Ruby the Hard Way #41 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hi I`m learning from LRtHW and I got stuck....
I have program like this:
require 'open-uri'
WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []
PHRASES = {
"class ### < ###\nend" => "Make a class named ### that is-a ###.",
"class ###\n\tdef initialize(###)\n\tend\nend" => "class ### has-a initialize that takes ### parameters.",
"class ###\n\tdef ***(###)\n\tend\nend" =>"class ### has-a function named *** that takes ### parameters.",
"*** = ###.new()" => "Set *** to an instance of class ###.",
"***.***(###)" => "From *** get the *** function, and call it with parameters ###.",
"***.*** = '***'" => "From *** get the *** attribute and set it to '***'."
}
PHRASE_FIRST = ARGV[0] == "english"
open(WORD_URL) do |f|
f.each_line {|word| WORDS.push(word.chomp)}
end
def craft_names(rand_words, snippet, pattern, caps=false)
names = snippet.scan(pattern).map do
word = rand_words.pop()
caps ? word.capitalize : word
end
return names * 2
end
def craft_params(rand_words,snippet,pattern)
names = (0...snippet.scan(pattern).length).map do
param_count = rand(3) + 1
params = (0...param_count).map {|x| rand_words.pop()}
params.join(', ')
end
return names * 2
end
def convert(snippet, phrase)
rand_words = WORDS.sort_by {rand}
class_names = craft_names(rand_words, snippet, /###/, caps=true)
other_names = craft_names(rand_words, snippet,/\*\*\*/)
param_names = craft_params(rand_words, snippet, /###/)
results = []
for sentence in [snippet, phrase]
#fake class name, also copies sentence
result = sentence.gsub(/###/) {|x| class_names.pop}
#fake other names
result.gsub!(/\*\*\*/) {|x| other_names.pop}
#fake parameter list
result.gsub!(/###/) {|x| param_names.pop}
results.push(result)
end
return results
end
# keep going until they hit CTRL-D
loop do
snippets = PHRASES.keys().sort_by { rand }
for snippet in snippets
phrase = PHRASES[snippet]
question, answer = convert(snippet, phrase)
if PHRASE_FIRST
question, answer = answer, question
end
print question, "\n\n> "
odp = gets.chomp
if odp == "exit"
exit(0)
end
#exit(0) unless STDIN.gets
puts "\nANSWER: %s\n\n" % answer
end
end
I understand most of this code, but I have a problem with:
for sentence in [snippet, phrase]
I know that it is a "for" loop and it creates a "sentence" variable, but how does the loop know that it need to look in a key and value of hash "PHRASES"
And my second "wall" is:
question, answer = convert(snippet, phrase)
It looks like it creates and assigns "question" and "answer variables to the "convert" method with "snippet" and "phrase" parameters... again how does it assigns "question" to a key and answer to a value.
I know that this is probably very simple but as for now it blocks my mind :(
For your first question about the for-loop:
Look at where the for-loop is defined. It's inside the convert() method, right? And the convert() method is passed two arguments: one snippet and one phrase. So the loop isn't "looking" for values in the PHRASES hash, you are the one supplying it. You're using the method's arguments.
For your second question about assignment:
In Ruby we can do something called "destructuring assignment". What this means is that we can assign an array to multiple variables, and each variable will hold one value in the array. That's what's happening in your program. The convert() method returns a two-item array, and you're giving a name (question and answer) to each item in the array.
Here's another example of a destructuring assignment:
a, b, c = [1, 2, 3]
a # => returns 1
b # => returns 2
c # returns 3
Try this out in IRB and see if you get the hang of it. Let me know if I can help clarify anything, or if I misunderstood your question. You should never feel bad about asking "simple" questions!

Separate subhash from hash [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have the following hash_of_student_and_grades.
{132=>{"Design"=>6, "English"=>5, "Humanities"=>5, "Languages"=>6, "Math"=>6, "Music"=>7,
"PE"=>6, "Science"=>6, "Theatre"=>6},
134=>{"Design"=>7, "English"=>6, "Humanities"=>6, "Languages"=>6, "Math"=>5, "Music"=>6,
"PE"=>6, "Science"=>7, "Art"=>6},
136=>{"Design"=>5, "English"=>4, "Humanities"=>5, "Languages"=>6, "Math"=>6, "Music"=>6,
"PE"=>7, "Science"=>5, "Theatre"=>6},...}
Now I want to make hash with key like this.
id132={"Design"=>6, "English"=>5, "Humanities"=>5, "Languages"=>6, "Math"=>6, "Music"=>7,
"PE"=>6, "Science"=>6, "Theatre"=>6}
id134={"Design"=>7, "English"=>6, "Humanities"=>6, "Languages"=>6, "Math"=>5, "Music"=>6,
"PE"=>6, "Science"=>7, "Art"=>6}
...
...
UPDATE:
I have done this so far. But it does not assign each hash to key.
resulthash.each {|key, value| puts key=value}
# outputs
{"Design"=>6, "English"=>5, "Humanities"=>5, "Languages"=>6, "Math"=>6, "Music"=>7, "PE"=>6, "Science"=>6, "Theatre"=>6}
{"Design"=>7, "English"=>6, "Humanities"=>6, "Languages"=>6, "Math"=>5, "Music"=>6, "PE"=>6, "Science"=>7, "Theatre"=>6}
How can I accomplish this?
You can't use digits as variable names, but if it would be id132, id133 etc you can accomplish this using metaprogramming and instance variables:
hash = {"i1"=>{"a"=>"b"}, "i2"=>{"c"=>"d"}}
hash.each { |key, value| instance_variable_set("##{ key }", value) }
puts #i1 # => {"a"=>"b"}
Because you can(ruby gives you ability to shoot your foot),here is answer:
In ruby id32 is the name of variable.
Hash's key can be any type: number, string... object.
Basic types(number, string, nil, false, true) are evaluated like this:
n1 = 2
n2 = 2
h = {2 => 42}
h[n1] # 42
h[n2] # 42
In other words you get/set hash's key 2 not n1 or n2. It would be hard to change basic types.
Objects, on other hands, you can modify:
class N
def initialize name
#name=name #contains name, like `id32`, `id34`
end
def to_s #this method let you show any text, here name(for example `id32`)
"#{#name}"
end
end
id32 = N.new 'id32'
h={id32 => 42}
#{id32=>42}
#adding more keys/values
id34 = N.new 'id34'
h[id34] = 'some value'
and... that's just basics.
what lots of rubist do:
They use symbols.
What are symbols?
It's type like string but there can be only one symbol!
puts :a.object_id
puts :a.object_id
puts :a.object_id
Code above prints 3 the same numbers because :a is only 1.
puts 'a'.object_id
puts 'a'.object_id
Strings are not the same.
Construction:
You prepend characters with ::
`:a`
or if it has weird character, prepend with : and surround with ' or ":
:'a'
To sum up:
Your code will look exactly the same, will be faster(no need for objects like above):
h ={:a => :b}
or from 1.9.x(i don't remember correct number) you can use this syntax too:
h = {a: :b}

Resources