Convert array to nested hash in ruby [closed] - ruby

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I have following array
['a', 'b', 'c']
How to convert it to hash like this bellow:
{'a' => { position: index of array element a }, 'b' ...., 'c' ... }
Best regards
Georgi.

First you could create an array like the following using the methods Array#map and Enumerator#with_index:
ary = ['a', 'b', 'c']
temporary = ary.map.with_index { |e, i| [e, { position: i }] }
# => [["a", {:position=>0}], ["b", {:position=>1}], ["c", {:position=>2}]]
Then you can convert the resulting array to hash using the Array#to_h method available since Ruby 2.1:
temporary.to_h
# => {"a"=>{:position=>0}, "b"=>{:position=>1}, "c"=>{:position=>2}}
For older versions of Ruby, the Hash.[] method will do:
Hash[temporary]
# => {"a"=>{:position=>0}, "b"=>{:position=>1}, "c"=>{:position=>2}}

['a', 'b', 'c'].each_with_index.reduce({}) do |s, (e, i)|
s[e] = { position: i }
s
end

Related

Search an attribute for a substring [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 7 years ago.
Improve this question
I am trying to remove all whitespaces from an object's attribute that contains a given substring. For example, I have an object event and attributes: 4IP2, 3IP5, 2IP1. I would like to do the following:
event[4IP2].gsub(/\s+/, '')
in a generic manner, i.e.,
event[*IP*].gsub(/\s+/, '')
which should work for all attributes 4IP2, 3IP5, 2IP1. Appreciate any help.
Assuming, that event is a hash, here you go:
▶ event = { '4IP2' => 'a b c', '3GG5' => 'ffff f', '2IP1' => 'ggg ' }
▶ event.map { |k, v| [k, /IP/ =~ k ? v.delete(' ') : v] }.to_h
#⇒ { "2IP1" => "ggg", "3GG5" => "ffff f", "4IP2" => "abc" }
If you want to replace the attributes in-place:
event.each {|k,v| v.gsub!(/\s+/, '') if /IP/ =~ k}
Otherwise, to create a copy:
Hash[event.map {|k,v| [k, /IP/ =~ k ? v.gsub(/\s+/, '') : v]}]

Ruby : How to take the next element of a array? [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
I got this tab :
["aaaaaaaaaaaaaaaaaaa",
"15/87/2014r",
"2453/NRc05",
"xxxxxxxxxxxxxxxxxxxxxxxxxx",
"Adaptée",
"09/12/2013",
"pub.pdf"]
And I only want "xxxxxxxxxxxxx" for example.
I found .next.element(s) but I got no idead of how to use it.. :/
Array#each returns an Enumerator:
arr = [1, 2, 3]
enum = arr.each
enum.next
#=> 1
enum.next
#=> 2
enum.next
#=> 3
enum.next
#=> StopIteration: iteration reached an end
Update
Regarding your comment
I have a array with some datas, and I wanted to save them in a hash with names like... {Name : aaaaa, First Name : bbbbbb} etc etc etc
Rather than calling next over and over again (I assume you are doing something like this):
data = ["John", "Doe"]
enum = data.each
hash = {}
hash[:first_name] = enum.next
hash[:last_name] = enum.next
# ...
You can combine two arrays with Array#zip and convert it to a hash using Array#to_h:
data = ["John", "Doe"]
keys = [:first_name, :last_name, :other]
keys.zip(data).to_h
#=> {:first_name=>"John", :last_name=>"Doe", :other=>nil}

How to use multiple .each statements in ruby?

I want to do something like this,
for topic.sections.each do |section| and topic.questions.each do |question|
print section
print question
end
I want both sections and questions simultaneously, the output will be like this:
section 1
question 1
section 2
question 2
I know what i did there is foolish, but, what is the exact way to do this or is this even possible?
Use Enumerable#zip.
For example,
sections = ['a', 'b', 'c']
questions = ['q1', 'q2', 'q3']
sections.zip(questions) { |section, question|
p [section, question]
}
# => ["a", "q1"]
# => ["b", "q2"]
# => ["c", "q3"]
Then do below with the help of Enumerable#zip:
topic.sections.zip(topic.questions) do |section,question|
p section
p question
end

How to make a copy of an array and manipulate its element in 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 9 years ago.
Improve this question
I have this array which I would like to copy and change an element's value. How can I do it (Ruby 1.9.3p429)
a = Array.new(2,"test") #a => ["test","test"] #a.object_id => 21519600 #a[0].object_id => 21519612
b = a.clone #b => ["test","test"] #b.object_id => 22940520 #b[0].object_id => 21519612
c = a.dup #c => ["test","test"] #c.object_id => 22865176 #c[0].object_id => 21519612
d = Array.new(a) #d => ["test","test"] #c.object_id => 23179224 #d[0].object_id => 21519612
c[0].upcase! #produces #a => ["TEST","TEST"], #b => ["TEST","TEST"], #c => ["TEST","TEST"] ...`
In Ruby every object is actually a reference to object so if you have array
x = [a, b, c, d]
and copy it into another array
y = x.clone
it will copy references to original objects, not objects themselves.
To do exactly what you want you would have to copy objects in a loop, however you're too focused on how you want to achieve array copying, instead of achieving your ultimate goal, get a new array which consists of upcased items of the original array.
Explore the Enumerable module and you will find things like #map, #select, #inject, etc. For instance this is how you get a copy of array with all names upcased:
["test", "test"].map { |element| element.upcase }
From your comment, you seem to want to upcase "c[0] only". I don't understand why you need to capitalize via a duplicate of a, but here is how to do it.
a = Array.new(2){"test"}
c = a.dup
c[0].upcase!
a # => ["TEST", "test"]

extracting non-empty value in 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 8 years ago.
Improve this question
pry(main)> s = {:a =>2, :d=>'foo', :x => ' ', :n => true, :z => nil}
=> {:a=>2, :d=>"foo"}
pry(main)> s.each do |k,v| p k unless v.empty? end
NoMethodError: undefined method `length' for 2:Fixnum
I understand it happens because fixnum does not have empty methods. Then how to solve this problem in a slick way, no nasty finding data type first and then check it? I want to print those k where v has some value. Yes true is considered a value, but not bunch of spaces. For me "have value" means non-empty characters and boolean true.
With your updated comments, I think that is what you want.
s = {:a =>2, :d=>'foo', :x => ' ', :n => true, :z => nil}
s.each { |k,v| p(k) if !!v && !v.to_s.strip.empty? }
# :n
# :d
# :a
Quick solution:
s.each {|k,v| p k unless v.to_s.empty?}

Resources