Ruby, print all the hashes "subfield" in one row - arrays

I have a JSON array structured like this:
{"elements":[{"ECL001":{"description":"First Element", "max_level":3, "size":10}},{"ECL002":{"description":"Second Element", "max_level":4, "size":1}}]}
I'm parsing my structure and then I print data if condition are satisfied.
require 'json'
x = JSON.parse(File.open('data_elements.dat').read)
elements = x["elements"]
elements.each do |elem_specific|
elem_specific.each do |id, data|
if data['max_level'] > 3
puts "#{data['description']}, #{data['max_level']}, #{data[size]}"
end
end
end
It's work correctly, but is there a faster solution to prints data?
I mean ... Is possible replace this
puts "#{data['description']}, #{data['max_level']}, #{data[size]}"
with something like
puts "#{data[*ALL]}"

I solved it!
I found this:
puts "#{data.values}" # Print all Values
puts "#{data.keys}" # Print all Keys

Related

Print elements of ruby array line by line after splitting a single string with "\n" condition

I have a single string, achieved using backticks of the following form:
output = `git log`
then, I have splitted the result where there are "\n" and the result went into an array of the form:
array = output.split("\n")
then, I am just trying to output the result in the screen, however, when I am using
array.each do |a|
puts a
end
I am getting as a result a double line of the form:
result after puts
(empty line)
result after puts etc
when my preferred result is a single line of the form:
result after puts
result afters puts etc
I tried to perform this with print, but I am getting:
result after puts result after puts etc
in a single line.
Can you please help me?
The issue is when you split using \n, if there are two \n characters then an empty "" gets added to the array.
eg: test = ["this","","is","test"]
Now if you do,
test.each do |a|
puts a
end
The o/p will be,
this
// a new line will come here.
is
test
so you should reject the empty values,
test2 = test.reject{ |value| value == ""}
test2.each do |a|
puts a
end
Result is,
this
is
test
In same way,
output = `git log`
array = output.split("\n")
array2 = array.reject{ |value| value == ""}
array2.each do |a|
puts a
end
This will give you the correct result.
Thanks to #AndreyDeineko, we have that:
"The issue is when you split using \n if there are two \n characters then an empty "" gets added to the array. Howcome? a = "1\n2\n3\n4\n"; a.split("\n") #=> ["1", "2", "3", "4"].
Therefore, array.each { |a| a } will work for you"
It did not work 100% for me, but using his answer, I manage to achieve the required result which is:
array.each { |a| a }
puts array

Sort method in Ruby

I wrote method, to sort array of user inputs(integers) from low to high and reverse. Code looks like:
def alphabetize(arr, rev=false)
arr.sort!
if rev==true
arr.reverse!
end
return arr
end
puts "enter your numbers with 'space' between them"
text = gets.chomp
numbers = text.split(" ")
numbers.each do |element|
element.to_i
end
puts alphabetize(numbers)
First time i tried only numbers from 0 to 9, and method had worked correct. But then i tried to input numbers like 1112, 11, 22 and after sorting procedure, i had got result like this "11 1112 22". After this, i tried to change code this way:
def alphabetize(arr, rev=false)
arr.sort!{|a, b| a.to_i <=> b.to_i}
if rev==true
arr.reverse!
end
return arr
end
puts "enter your numbers with 'space' between them"
text = gets.chomp
numbers = text.split(" ")
puts alphabetize(numbers)
And this way my code works correct and sorting input of 11, 1112, 22 produce the result that i expect: "11, 22, 1112". Looks like i have solved the problem, but i really want to understand the difference between first version and second version of code. Why method sort works in different ways?
each does not replace the elements in an array - it simply returns the array itself (without change).
You might prefer to use map:
numbers = numbers.map do |element|
element.to_i
end
Or, better yet, use map!, which actually changes the array itself, rather than return the changed array:
numbers.map! do |element|
element.to_i
end
You can also use the following shorthand:
numbers.map! &:to_i
Looks like in the first place you still comparing strings instead of integers.
In fact, in the first place you don't convert elements to integers:
numbers.each do |element|
element.to_i
end
The script below don't replace strings with integers in array.

Adding items to a new array with index

Trying to make a method skip_animals that takes an animals array and a skip integer and returns an array of all elements except first skip number of items.
input: skip_animals(['leopard', 'bear', 'fox', 'wolf'], 2)
expected output: ["2:fox", "3:wolf"]
def skip_animals(animals, skip)
arr = Array.new
animals.each_with_index{|animal, index| arr.push("#{animal}:#{index}") }
puts arr.drop(skip)
end
This instead puts each output on a separate line and doesn't add them to the array arr. I thought the arr.push would add them correctly. What do I have to do to get the elements added to the array?
I want to use these methods, not map or something more advanced. I need to tinker with this each_with_index line, not overhaul it.
(This is a challenge on Hackerrank, so it uses STDIN and STDOUT)
EDIT
Here is my updated code with p instead of puts. It's giving me a weird output of two different arrays, not sure why.
def skip_animals(animals, skip)
arr = Array.new
animals.each_with_index{|animal, index| arr.push("#{index}:#{animal}") }
p arr.drop(skip)
end
This gives me two lines of output:
["3:panda", "4:tiger", "5:deer"]
["0:leopard", "1:bear", "2:fox", "3:wolf", "4:dog", "5:cat"]
I'm assuming the top is the correct array, but I don't get why the second is printing also, or why it has a different set of animals.
Use p instead of puts.
irb(main):001:0> puts ['1', '2']
1
2
=> nil
irb(main):002:0> p ['1', '2']
["1", "2"]
According to the documentation, puts:
Writes the given objects to ios as with IO#print. Writes a record
separator (typically a newline) after any that do not already end with
a newline sequence. If called with an array argument, writes each
element on a new line. If called without arguments, outputs a single
record separator.
BTW, I would code like this (using Enumerable#map + returning result instead of printing inside the function):
def skip_animals(animals, skip)
animals.drop(skip).each_with_index.map { |animal, index|
("#{index + skip}:#{animal}")
}
end
p skip_animals(['leopard', 'bear', 'fox', 'wolf'], 2)
just remove puts remove form this line puts arr.drop(skip)
def skip_animals(animals, skip)
arr = Array.new
animals.each_with_index{|animal, index| arr.push("#{animal}:#{index}") }
arr.drop(skip)
end

Using arrays in regular expressions?

Does anyone know if there is a way to use an array in a regular expression? suppose I want to find out if somefile.txt contains one of an array's elements. Obviously the code below doesn't work, but is there something similar that does work?
array = [thing1 thing2 thing3]
file = File.open("somefile.txt")
file.each_do |line|
if /array/.match(line)
puts line
end
Basically I've got a file that contains a list of words that I need to use as search terms in another large file, and I'd like to avoid something like this:
($somefile =~ /(thing1|thing2|thing3)/)
You can use Regexp.union, it returns a Regexp that matches any of the given regex. The argument patterns could be either String or Regexp:
Regexp.union(%w(thing1 thing2 thing3))
#=> /thing1|thing2|thing3/
or
Regexp.union(/thing1/, /thing2/, /thing3/)
#=> /(?-mix:thing1)|(?-mix:thing2)|(?-mix:thing3)/
Use:
x = ['qwe', 'asd', 'zxc']
file = File.open("somefile.txt")
regexp = /(#{x.join '|'})/
file.each_do |line|
puts line if regexp.match(line)
end

fixing horrible formatting when adding to ruby array from params

I have some code that adds to a session array like so:
if policy_session[:modalities] #array exists just add new value to it
policy_session[:modalities] << [params[:modality], policy_session[:mode_list]]
else #the array does't exist yet, so create and add first one.
policy_session[:modalities] = [params[:modality], policy_session[:mode_list]]
but this produces horrible formatting on my :modalities array. It looks like this:
>> policy_session[:modalities]
>># [["var_1"], "1",[["var_2"], ["2"]], [["var_3"], ["1"]]]
Which is a total pain to try and iterate over later in my program.
I have tried a bunch of different things, but haven't come up with anything that really looks better then this.
How do I create and then add to the array such that my output will be readable? And all formatted the same!
I would like something like this:
>>policy_session[:modalities]
>># [["var_1", "1"], ["var_2", "2"], ["var_3", "1"]]
Something like this...
policy_session[:modalities] ||= [] # set it to an empty array if nil
policy_session[:modalities] << [params[:modality], policy_session[:mode_list]]
Edit: To get rid of the extra []'s...
policy_session[:modalities] ||= [] # set it to an empty array if nil
policy_session[:modalities] << [params[:modality], policy_session[:mode_list]].flatten

Resources