error adding ruby code on a structure [closed] - ruby

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 6 years ago.
Improve this question
I have a structure defined in 'strct'. Its possible to add some ruby code like the next example?
def strct(i)
{
"mwdata": [
i.times do //incorrect
{
"mwtype": "cell",
"mwsize": [
1,
3
],
"mwdata": [
10,
23,
199
]
}
end //incorrect
]
}
end

You can multiply arrays by using *, but this will create an Array of references to the same Hash object, changing one, changes all of them. (as #mudasobwa pointed out in the comments)
def strct(i)
{ "mwdata": [ {...} ] * i }
end
It's also possible to use tap:
def strct(i)
{ "mwdata" => [].tap do |array|
i.times do
array << { .... }
end
end
}
end
Or inject:
def strct(i)
{ "mwdata" => 1.upto(i).inject([]) do |array|
array << { .... }
end
}
end
Note
I understand the reason for this question, as I have often found myself doing something like:
def strct(i)
result = { "foo" => [] }
i.times do
result["foo"] << "Something #{i}"
end
result
end
Quick googling gave me this: hash_builder.rb that works like jsonbuilder and can be used to create hash "templates".

Related

Find the specific number from Array.collect [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 6 years ago.
Improve this question
I want to find out what's the first, the second, and the third result, so that I can do if firstnumber==secondnumber && secondnumber==thirdnumber. How could I find those numbers on the results?
numbers = 3.times.map { Random.new.rand(0..10000) }
prizes = numbers.map do |x|
case x
when 1..3000
[ '7', 10000 ]
when 3001..6000
[ "Cherries", 500 ]
when 6001..10000
[ "Diamond", 400 ]
end
end
puts "Your results are: #{prizes.collect { |p| p[0] }.join(", ")}!
I tried to use p[0][0], but it gives the first letter instead.
Say if:
results = prizes.collect { |p| p[0] } #=> ["Diamond", "Cherries", "7"]
Then do the following to get at each result:
results[0] #=> "Diamond"
results[1] #=> "Cherries"
results[2] #=> "7"
You could also use results.first to get the first element. If you happen to be working in Rails you can even do the following:
results.second #=> "Cherries"
results.third #=> "7"
Here's a fine way to do this:
numbers = 3.times.map { Random.new.rand(0..10000) }
prizes = numbers.map do |x|
case x
when 1..3000
{ name: '7', val: 10000 }
when 3001..6000
{name: "Cherries", val: 10000 }
when 6001..10000
{name: "Diamond", val: 400 }
end
end
# You could replace 'map' with 'collect' here and have the same results
prizes_string = prizes.map { |p| "#{p[:name]}: #{p[:val]}" }.join(" and ")
puts "Your results are: #{prizes_string}!"

Converting an array of numbers to characters 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 6 years ago.
Improve this question
The to_chr function is supposed to return the encrypted array but converted to characters. I have tried many things and commented out the ones that didn't work.
class Encrypt
def initialize(code, string)
#code = code
#string = string
#encrypted = []
end
def to_byte
#string.each_byte do |c|
#encrypted.push(c + #code)
end
print #encrypted
end
def to_chr
n = #encrypted.length
# n.times do |i|
# #encrypted.push(i.chr)
# end
print #encrypted[0].chr
# #encrypted.each do |x|
# #encrypted.push(x.chr)
# end
# print #encrypted
end
end
goop = Encrypt.new(2, "hello")
goop.to_chr
#=> in `to_chr': undefined method `chr' for nil:NilClass (NoMethodError)
You create instance of Encrypted method, but you set #code = 2, #string = "Hello" and #encrypted = []. So if you call #encrypted[0], ruby return nil.
So you can modify your class like this:
class Encrypt
def initialize(code, string)
#code, #string, #encrypted = code, string, []
end
def to_byte
#string.each_byte { |c| #encrypted << c + #code }
end
def to_chr
to_byte if #encrypted.empty?
#encrypted.map(&:chr)
end
end
goop = Encrypt.new(2, "hello")
p goop.to_chr
# => ["j", "g", "n", "n", "q"]
I hope this helps
def to_chr
#encrypted.each do |i|
print i.chr
end
print "\n"
end
Make sure to call to_byte prior to to_chr
goop = Encrypt.new(2, "hello")
goop.to_byte
goop.to_chr
returns:
jgnnq

Assigning hash inside each does not work [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
This:
(0..8).each do |n|
"a_#{n}" = {}
end
gives me an error "syntax error, unexpected '=', expecting keyword_end". I wanted to create a_0 = {}, a_1 = {}, a_2 = {} etc.
I think you want an array of hashes.
a = []
(0..8).each do |n|
a[n] = {}
end
Result:
a #=> [{}, {}, {}, {}, {}, {}, {}, {}, {}]
a[0] #=> {}
a[1] #=> {}
...etc...
although depending on what you need to do next, this type of initialization may not be necessary.
binding.instance_eval do (0..8).each do |i|
local_variable_set("a_#{i}", {})
...
end end
Without bad magic, you won't get the functionality you want (there are ways to do that but they are bad and hacky). Use a hash or array instead.

Idiomatically removing bracketted list elements [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 9 years ago.
Improve this question
How can one generate a new list has all the elements of old-list except for some parts bracketted between line where f1(start_line) is true and f2(end_line) is true
Naive code
def remove_bracketted(orig_list)
ignore_flag = false
new_list = []
orig_list.each do |v|
if f1(v)
ignore_flag = true
elsif f2(v)
ignore_flag = false
else
new_list << v unless ignore_flag
end
end
end
For instance, with the following definitions of f1 and f2
def f1(v)
v == "{"
end
def f2(v)
v == "}"
end
when run on
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Some other text
one should get
foo(a,b)
bar(a,b)
Some other text
Kindly note that f1 and f2 can be any function of type a -> Bool where list elements are all of type a and not just comparison to an open brace and close brace.
Edit:
I was looking for a solution like this which works if there is only one such pair
new_list = old_list.take_while(not(condition1)).concat(old_list.drop_while(not(condition2)))
This might be a place where the flip-flop operator would be useful:
def val1; '{' end
def val2; '}' end
p ['a','b','{','a','}','f','d','d'].reject{|x| true if (val1==x)..(val2==x)}
#=> ["a", "b", "f", "d", "d"]
p ['a','b','{','a','}','f','d','d'].select{|x| true if (val1==x)..(val2==x)}
#=> ["{", "a", "}"]
ScriptDevil, i guess some people won't like your way of making a question so i suggest asking it somewhat politer and not offer us a 'task' like we are in class. We are here to help and you should show us what you tried yourself.
Here is a way of doing what you want.
class String
def replace_between start, ending, replace_with
gsub(/#{start}[^#{ending}]*#{ending}/m, replace_with)
end
end
txt = %[
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Some other text
]
puts txt.replace_between '{', '}', ''
# oo(a,b)
# bar(a,b)
# Some other text

Retrieve nested hash values ruby [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 a nested Hash like this :
{
:a=>{
:toto=>{
:foo=>10,
:bar=>11,
:baz=>12
},
:titi=>"a"
},
:b=>{
:toto=>{
:foo=>31,
:bar=>45,
:baz=>78
},
:titi=>"b"
}
}
My goal is to sum all the :baz values. I'm sure there is a beautiful way to do this in ruby. Any idea?
Thanks.
#inject is very powerful method that works for both arrays and hashes. You can walk through values of hash and sum the needed key to the total sum.
hash.inject(0) { |sum, (_,v)| sum += v[:toto][:baz] } # => 90
h = {
:a=>{
:toto=>{
:foo=>10,
:bar=>11,
:baz=>12
},
:titi=>"a"
},
:b=>{
:toto=>{
:foo=>31,
:bar=>45,
:baz=>78
},
:titi=>"b"
}
}
h.inject(0){|sum,(_,v)| sum +=v.fetch(:toto,{}).fetch(:baz,0)}
This method finds all :baz elements, regardless of their path.
h = {
:a=>{
:toto=>{
:foo=>10,
:bar=>11,
:baz=>12,
},
:titi=>"a"
},
:b=>{
:toto=>{
:foo=>31,
:bar=>45,
:baz=>78,
},
:titi=>"b",
},
}
def sum_baz(hash)
hash.values.reduce(0) do |memo, elem|
if elem.is_a?(Hash)
memo += sum_baz(elem)
memo += elem[:baz] if elem[:baz]
end
memo
end
end
sum_baz(h) # => 90

Resources