Extract Substring from String / Ruby - ruby-on-rails

I get the datas from a variable called "apps".
And I have this datastructure:
{"id"=>001,
"name"=>"test01",
"users"=>
[{"id"=>01,
"name"=>"test02"},
{"id"=>02,
"name"=>"test03"}]}
How can I extract the namevalues from the users substring?
I have tried
apps.each do |test|
data = Hash.new
data['id'] = test['id']
data['name'] = test['name']
data['username'] = test['users.name']
userdata = data
userdata.each do |row|
File.write('test.yaml', row.to_yaml)
end
end
But that doesn't work.
desired output would be:
{"id"=>"01", "name"=>"test02","id"=>"02", "name"=>"test03"}

you just need to require 'yaml' in order to use it on Hash/Array classes, you don't need to iterate over array or hash, to_yaml already handles this for you.
require 'yaml'
data = {"id"=>001,
"name"=>"test01",
"users"=>
[{"id"=>01,
"name"=>"test02"},
{"id"=>02,
"name"=>"test03"}]}
File.write('test.yml', data["users"].to_yaml)

Related

Not able to place csv data in a Hash

I have a CSV file with two columns:
PPS_Id Amount
123 100
1234 150
I read data from this file and insert in a array using the code below:
CSV.foreach("filename.CSV", headers: true) do |row|
file_details << row.inspect # hash
end
I am then trying to push the data in the file_details into a hash with PPS_Id as key and Amount as Value, I am using the code below:
file_details_hash = Hash.new
file_details.each { |x|
file_details_hash[x['PPS_Id']] = x['Amount']
}
But when I print the result I get nothing just {"PPS_Id"=>"Amount"}
Can you please help
Your code, modified to work
You need to specify the column separator for your csv, and remove inspect.
require 'csv'
file_details = []
CSV.foreach("filename.CSV", headers: true, col_sep: "\s" ) do |row|
file_details << row
end
file_details_hash = Hash.new
file_details.each { |x|
file_details_hash[x['PPS_Id']] = x['Amount']
}
p file_details_hash
#=> {"123"=>"100", "1234"=>"150"}
It now returns what you expected to get.
Shorter solution
Read the csv, drop the first line (header) and convert to a Hash :
p CSV.read("filename.CSV", col_sep: "\s").drop(1).to_h
#=> {"123"=>"100", "1234"=>"150"}
First of all, you are collecting strings into an array (see String#inspect):
file_details << row.inspect
After that you call (sic!) String#[] on that strings:
x['PPS_Id'] #⇒ "PPS_Id", because string contains this substring
That said, your code has nothing but errors. You might achieve what you want with:
csv = CSV.parse(File.read("filename.CSV"), col_sep: "\s")
csv[1..-1].to_h
#⇒ {
# "123" => "100",
# "1234" => "150"
# }
Using inspect will save your CSV rows as strings, so obviously you won't be able get what you need. Instead try this:
file_details = CSV.read("filename.csv")
Read CSV directly will create an 2D array that you can then iterate over, which will look like this: [["PPS_Id", "Amount"], ["123", "100"], ["1234", "150"]]
From there you can slightly modify your approach:
file_details.each do |key, value|
file_details_hash[key] = value
end
To receive a hash like this: {"PPS_Id"=>"Amount", "123"=>"100", "1234"=>"150"}

Display Json in view

Im having problems trying to display in my view information comming from a json file. I have already parse it.
Here is my error:
When assigning attributes, you must pass a hash as an argument.
Extracted source (around line #23):
21 # #new_member.constructors = [driver['Constructors'][0]['name']]
22 # #new_member.points = [driver['points']]
23 #new_member.from_json(json)
#members << #new_member
end
# #new_member.constructors = [driver['Constructors'][0]['name']]
# #new_member.points = [driver['points']]
#new_member.from_json(json)
#members << #new_member
end
This is my controller:
require 'open-uri'
require 'json'
url = "http://ergast.com/api/f1/2014/driverStandings.json"
data = JSON.parse(open(url).read)
standings = data['MRData']['StandingsTable']['StandingsLists'][0]['DriverStandings']
#members = Array.new
standings.each do |driver|
json = standings.to_json
#new_member = Member.new
# #new_member.position = [driver['position']]
# #new_member.givenName = [driver['Driver']['givenName']]
# #new_member.familyName = [driver['Driver']['familyName']]
# #new_member.constructors = [driver['Constructors'][0]['name']]
# #new_member.points = [driver['points']]
#new_member.from_json(json)
#members << #new_member
If I uncommented the lines in the controller and delete these lines
#new_member.from_json(json)
json = standings.to_json
I get the following in the view
Name: ["Lewis"]
Name: ["Nico"]
That view is really close but is not what i need, I need the data without [" "],
so the view that I need is something like:
1 Lewis Hamilton Mercedes 384
Thanks in advance.
Alternative 1
Change the line:
#new_member.givenName = [driver['Driver']['givenName']]
into:
#new_member.givenName = driver['Driver']['givenName']
removing the external [ and ], so that the field #new_member.givenName that you're populating becomes a string rather than an array containing one string.
Alternative 2
Is it possible that, when looping through the standings hash, the driver temp variable is a Hash?
In this case it may be sufficient to do:
#members = Array.new
standings.each do |driver|
#members << Member.new(driver)
end
Bonus: you probably don't need to assign an instance variable #new_member, that gets overwritten at each iteration of the loop

Write bunch of hashes to a json file

Whats the right approach to write number of hashesh to a json file that can be parsed effeciently later on.
e.g:
hash1 = {:a=>1,:b=>'foo'}
hash2 = {:c=>3,:b=>'bar'}
...
hashN = {...}
File.open("data.json", "a") { |io| io.write(hash1.to_json)}
I can write a comma after each hash to the file, but this is not looking nice to me.. is it a better way to do it?
that can be parsed effeciently later on.
You will want to put your hashes in a list so that later you can load and parse everything in one sweep:
require 'json'
arr = []
arr << {:a=>1,:b=>'foo'}
arr << {:c=>3,:b=>'bar'}
json_str = arr.to_json
File.open("yourfile", 'w') { |file| file.write(json_str) }
Later on to load:
contents = File.read('yourfile')
arr = JSON.parse(contents)

Array only saves the last value in ruby on rails

I have a loop which outputs information I grabbed from a website. To make the information display in an readable fashion, I insert it into an array that will be displayed on my view page. However, The array does not store all the values retrieved and instead only saves the last value appended to it. In the end I can only get the last value inserted into the array to be displayed.
My controller file...
def home
scrape()
end
private
def scrape
require 'rubygems'
require 'nokogiri'
require 'open-uri'
time = Time.new
month = I18n.t("date.abbr_month_names")[time.month]
day = time.day
#strings = []
#United States
cities = [
"sfbay", "losangeles", "athensga", "phoenix", "santabarbara", "denver",
"panamacity", "miami", "austin", "bakersfield", "keys", "newyork"
]
cities.map do |city|
#Search Terms
search_terms = ["mechanic", "car", "tech"]
search_terms.map do |term|
escaped_term = CGI.escape(term)
url = "http://#{city}.craigslist.org/search/jjj?query=#{escaped_term}&catAbb=jjj&
srchType=A"
doc = Nokogiri::HTML(open(url))
doc.css(".row").map do |row|
date = row.css(".itemdate").text
a_tag = row.css("a")[0]
text = a_tag.text
link = a_tag[:href]
#strings == []
if date = "#{month} #{day}"
#strings << "#{date} #{text} #{link}"
end
end
end
end
end
In the view home.html.erb file...
<%= raw(#strings.join('<br />')) %>
So when I go to the home page, I'm only display the last value inserted into the array. What is wrong and how do I fix it?
For one thing you create a new array for every row for every city. (But don't, actually; the assignment is a compare, ==, at the moment.)
For another you set date equal to "#{month} #{day}" instead of doing a comparison.

Ruby on Rails 2 search string in Hash

I need help with this...
I have a hash like this:
#ingredients = Hash.new
#ingredients[1] = "Biscottes Mini(recondo)"
#ingredients[2] = "Abadejo"
#ingredients[3] = "Acelga"
#ingredients[4] = "Agua de Coco"
#ingredients[5] = "Ajo"
#ingredients[6] = "Almidón de Arroz"
#ingredients[7] = "Anillos Con Avena Integral cheerios (nestle)"
#ingredients[8] = "Apio"
I need to search into that hash in order to find "Biscottes Mini(recondo)" when I write "scotte"
Some help?
Thk!
Why do you use a Hash here and not an Array? You do not seem to use other keys than integers.
Anyway, this solution works for both Array and Hashes:
search_term = 'scotte'
# you could also use find_all instead of select
search_results = #ingredients.select { |key, val| val.include?(search_term) }
puts search_results.inspect
See http://ruby-doc.org/core/classes/Enumerable.html#M001488
You can call select (or find if you only want the first match) on a hash and then pass in a block that evaluates whether to include the key/value in the result hash. The block passes the key and value as arguments, so you can evaluate whether either the key or value matches.
search_value = "scotte"
#ingredients.select { |key, value| value.include? search_value }

Resources