display values of couchdb document - ruby

I have a document stored in couchdb which is like this -
{
"_id": "0f8baf09c680abdc434607dc77000bad",
"_rev": "2-c989a4c672d25b678aadfa4c37212404",
"XI": "gl11subjects",
"XII": "gl12subjects"
}
when I retrieve the document using the code
#value = CouchRest.get("url/db/docid")
#value.each do |key, value|
puts "Key: "+key+"value: "+value+
The above statement prints all the values in the json file, including _id and _rev.
How should I iterate through the #value to only get the key/value for XI and XII.

Here's one way:
#value.each do |key, value|
puts "Key: #{key} Value: #{value}" if key.include?("XI")
end
Inversely, you could do the following:
#value.each do |key, value|
puts "Key: #{key} Value: #{value}" unless key.include?("_")
end

Related

Recursive Function to retrieve a deeply nested hash

I have the following code:
ATTRIBUTES_TO_ANONYMIZE = [ { submitted_input: [:salutation, { user_location: [:city, :country, :full_address] }] }]
def runner
anonymize_data_hash(ATTRIBUTES_TO_ANONYMIZE)
end
def anonymize_data_hash(data, key=nil)
if data.is_a?(Hash)
data.each do |key, value|
anonymize_data_hash(value, key)
end
elsif data.is_a?(Array)
data.each do |value|
anonymize_data_hash(value, key)
end
else
puts "#{key}[#{data}]"
end
end
This generates the following output:
submitted_input[salutation]
user_location[city]
user_location[country]
user_location[full_address]
The output I really need is:
submitted_input[salutation]
submitted_input[user_location][city]
submitted_input[user_location][country]
submitted_input[user_location][full_address]
Does anyone have an idea how I could achieve this output. Any help is highly appreciated
In your recursive calls keep track of the nesting instead of just forwarding the key from the last hash.
def anonymize_data_hash(data, path=[])
if data.is_a?(Hash)
data.each do |key, value|
anonymize_data_hash(value, path + [key])
end
elsif data.is_a?(Array)
data.each do |value|
anonymize_data_hash(value, path)
end
else
path = path.clone
key = path.shift
path = (path + [data]).map{|x| "[#{x}]"}.join
puts "#{key}#{path}"
end
end

Editing yaml hashmap with ruby and rake

I have a yaml who's elements need to be filled by a user... sounds simple enough. I am attempting to read the file, print the keys, ask for a value, and store the updated file.
cnfg.yml:
thing:
something:
another_thing:
much_depth:
such_yml:
...
Here is my code thus far:
task :setup_cnfg do
config = YAML.load_file 'cnfg.yml'
config.each do |key, value|
puts key
value.each do |k, v|
print " #{k}: "
v = STDIN.gets.chomp() #STDIN is there due to some strange rake shenanigans
end
end
File.open('cnfg.yml','w') {|f| f.write config.to_yaml}
end
If I print 'v' after I capture the input it does show the intended value but if i print the hash afterwords all imputed values will be gone!
What would I do in order to correctly populate and store all of my data fields?
You should actually assign the new v back to the value hash:
task :setup_cnfg do
config = YAML.load_file 'cnfg.yml'
config.each do |key, value|
puts key
value.each do |k, _|
print " #{k}: "
value[k] = STDIN.gets.chomp()
end
end
File.open('cnfg.yml','w') {|f| f.write config.to_yaml}
end

How to get the key of a hash

Right now I have a double hash called data like the following:
data [name][action]
ie
data = {"Mike" => {"Walked" => 13, "Ran" => 5}, "Steve" => {...}}
For this particular hash, I don't actually know the keys in the hash, I just want to iterate over it, like so:
data.each |item| do
#how to get the key name for item here?
puts item["Walked"].to_s
puts item["Ran"].to_s
end
I'd like to get the key so I can display it in a table beside the values.
You can iterate over a hash using:
data.each do |key, value|
end
You can use each with a key, value syntax, as described in the each documentation:
data.each do |key, values|
puts key.to_s
values.each do |value|
value.to_s
end
end
You could also use keys or values depending on what you wanted to achieve.
data.keys.each do |key|
puts key #lists all keys
end
data.values.each do |value|
puts value #lists all values
end
data.keys.first #first key
and so on.

How to access complex array of hashes

I have this to work with:
[
["app1", {"name"=>"name1", "path"=>"xyz.com/"}],
["app2", {"name"=>"name2", "path"=>"xyz.com/"}],
["app3", {"name"=>"name3", "path"=>"xyz.com/"}],
# etc.
]
I want to be able to access each name and path so I tried:
apps.each do |key, value|
value.each do |key, value|
puts value
end
end
but this returns an Enumerator. Any idea how I can do this?
apps = [["app1", {"name"=>"name1", "path"=>"https://xyz.com/"}], ["app2", {"name"=>"name2", "path"=>"https:/xyz.com/"}], ["app3", {"name"=>"name3", "path"=>"https://xyz.com/"}]]
apps.flatten.each do |t|
next unless t.class == Hash
next unless t.key?("name")
next unless t.key?("path")
puts t.inspect # now t is a hash that has both "name" and "path" keys - do what you want
end
This will handle even a bit more complex cases when you have different structure for different elements.
I think your first each loop is only looping over an array, so it would be:
apps.each do |app|
app.each do |key, value|
puts key # would be app1 in the first array
puts value["name"]
puts value["path"]
end
end
ar = [
["app1", {"name"=>"name1", "path"=>"xyz.com/"}],
["app2", {"name"=>"name2", "path"=>"xyz.com/"}],
["app3", {"name"=>"name3", "path"=>"xyz.com/"}]
]
#Get a specific app:
p ar.assoc("app2").last["name"]
#Get all names and paths
ar.each{|app| name, path = app.last["name"], app.last["path"]}

separating key and multiple values for print with .each

I'm probably trying to be hard headed about this. I'm trying to format hash key and and array of values for output to user. Ruby-doc give me the code for it for one value. http://www.ruby-doc.org/core/classes/Hash.html#M002861
h = { "a" => 100, "b" => 200 }
h.each {|key, value| puts "#{key} is #{value}" }
I'm trying to get
h = { "a" => [100,'green'], "b" => [200,'red'] }
h.each {|key, m,n| puts "#{key} is #{m} and #{n}"}
produces:
a is 100 and green
b is 200 and red
I've had some luck with
h.each{|key,m,n| puts "#{key} is #{[m,'n']} "}
it produces:
a is 100green
b is 200red
I need some space between my array of elements, how do I go about doing that?
h.each {|key, (m, n)| puts "#{key} is #{m} and #{n}"}
h.each { |key, value| puts "#{key} is #{value.first} and #{value.last}" }
I'm a fan of each_pair for hashes:
h.each_pair {|key, val| puts "#{key} is #{val[0]} and #{val[1]}" }
Or
h.each_pair {|key, val| puts "#{key} is #{val.join(' and ')}"}
h.each {|k,v| puts "#{k} is #{v[0]} and #{v[1]}"}

Resources