Set array elements (string) as variable name in Ruby - ruby

I have the following array, that I use to later write the header on an Excel file.
fields = ["fileName", "type", "id"]
And then I have the following code that reads values from an XML:
filename = xml.xpath('//path/filename').text
type = xml.xpath('//path/type').text
id = xml.xpath('//path/id').text
The I iterate the initial array (fields) in order to set the Excel cells to the values extracted in the previous step:
row = 2
c = 1
fields.each do |content|
ws.Cells(row,c).Value = content
c = c + 1
I'm trying to have the array's (fields) contents to variable names instead of strings in order to be able to reuse the head fields.
Can anyone recommend a way of making it possible?

This sounds like you need to use a Hash to associate field names to the values you extracted:
fields = {
"fileName" => xml.xpath('//path/filename').text,
"type" => xml.xpath('//path/type').text,
"id" => xml.xpath('//path/id').text
}
row=2
c=1
fields.each do |key,value|
ws.Cells(row,c).Value = value
c=c+1
end

Related

Ruby: Convert String to Symbol during String Interpolation

I am looping over a block of code, each time increasing variable "filter_index", from 1, to 2, to 3... etc.
I'd like to use this variable to access the different symbols:
filter1_field_name,
filter2_field_name,
filter3_field_name
#filter1_field_name = "Region"
#filter2_field_name = "Country"
#filter3_field_name = "City"
SELECT_STATEMENT = "GROUP BY "
numberOfFilters = 3
filter_index = 1
numberOfFilters.times do #Number of iterations
filter_field_name = "#filter#{filter_index.to_s}_field_name"
SELECT_STATEMENT.sub! "GROUP BY", "AND #{filter_field_name.to_sym} GROUP BY"
filter_index += 1
end
puts SELECT_STATEMENT
This results in
AND #filter1_field_name AND #filter2_field_name AND
#filter3_field_name GROUP BY
But the desired result is
AND Region AND Country AND City GROUP BY
I'm wondering why filter_field_name.to_sym is not working (or rather, what I'm doing wrong)?
You can use instance_variable_get function to get variable value.
Replace the line
filter_field_name = "#filter#{filter_index.to_s}_field_name"
with
filter_field_name = instance_variable_get("#filter#{filter_index.to_s}_field_name")
EDIT:
I think you can put the field names into an array and concat the values with join method.
fields = ['Region','Country','City']
fields.join(' AND ')
you can use instance_variable_get or eval
filter_field_name = instance_variable_get("#filter#{filter_index.to_s}_field_name")
or
filter_field_name = eval("#filter#{filter_index.to_s}_field_name")

Getting date value from an array hash

I have a hash that looks like
tagArray = { :"2014Date"=>["11/22/2014"], :"2015Date"=>["03/21/2015"] }
Since i already know for a given key, there is only one element in the array of 'values', how can you get just the value not as an array?
value = tagArray[:"2015Date"]
=>
value = ["04/12/2015"]
You can just index the array then and get the date like
value = value.fetch(0).to_s
=>
value = "04/12/2015"
However I am looking for a more elegant way of doing it.
Note: I am using Ruby 2.2, so need to 'strp' the date first to change it from mm/dd/yyyy format which is the end goal.
This is a bit simpler:
value = tagArray[:"2015Date"].last
=>
value = "03/21/2015"

How to assign column name from variable

I want to assign a value to a table column. The column selected needs to be based on a variable. How do you do this?
If #language = "german" than I want to assign #new_word.german = string
#new_word = Word.new
#new_word.german = string
#new_word.save
So how would I assign .german using #language? #new_word.#language :/
x = "german"
#new_word.send("#{x}=", "some value")
#new_word[x] = "some value" # may end up skipping overrides/callbacks, etc though. check the docs.

Ruby put in order columns when creating CSV document from Mongoid

I need to create CSV document from database. So I want to organise columns in particular order and I have template of this order and this template stored as array of headers
header = ["header1", "header2", "header3", "header4", "header5"]
record = [{"header4" =>"value4"}, {"header3" =>"value3"}, {"header5"=>"value5"}, {"header1"=>"value1"}, {"header2"=>"value2"}]
I need to get array like tis
record = [{"header1" =>"value1"}, {"header2" =>"value2"}, {"header3"=>"value3"}, {"header4"=>"value4"}, {"header5"=>"value5"}]
but when I doing
csv<< mymodel.attributes.values.sort_by! { |h| header.index(h.keys[0])
It does not work
When you call mymodel.attributes, you get a Hash back which maps attributes names (as strings) to their values. If your attribute names are header1 through header5 then mymodel.attributes will be something like this:
{
'header1' => 'value1',
'header2' => 'value2',
'header3' => 'value3',
'header4' => 'value4',
'header5' => 'value5'
}
Of course, the order depends on how things come out of MongoDB. The easiest way to extract a bunch of values from a Hash in a specified order is to use values_at:
mymodel.attributes.values_at(*header)

Ruby: Hash w/ Arrays, Returning Associated Key If Value Is In Array

New to Ruby and have run out of ideas. I have an array of books that I would like to 1) Shelve 2) Find which shelf it is on 3) Remove it from the associated shelf if found. For brevity I have an array of 6 books. Each shelf contains 5 books.
library_catalog = [ "Book1", "Book2", "Book3", "Book4", "Book5", "Book6" ]
shelves = Hash.new(0)
catalog_slice = library_catalog.each_slice(5).to_a
count = 1
catalog_slice.each do | x |
shelves.merge!(count=>x)
count+=1
end
From this I know have a Hash w/ arrays as such
{1=>["Book1", "Book2", "Book3", "Book4", "Book5"], 2=>["Book6"]}
This is where I'm having trouble traversing the hash to find a match inside the array and return the key(shelf). If I have title = "Book1" and I am trying to match and return 1, how would I go about this?
I think this should work.
shelves.select { |k,v| v.include?("Book1")}.keys.first
selected the hashes that have a value equal to the title you are looking for (in this case "Book1")
get the keys for these hashes as an array
get the first entry in the array.
to remove the Book from the shelf try this:
key = shelves.select { |k,v| v.include?("Book1")}.keys.first
shelves[key].reject! { |b| b == "Book1" }
get a reference to the array and then reject the entry you want to remove

Resources