I have an array of hashes generated by map
arr = current_order.order_items.map{|oi|[{name:oi.name,price:oi.price}]
[{:name=>"Jacket", :price=>300},
{:name=>"Bag", :price=>650 },
{:name=>"Suit", :price=>300}].to_s
i need to make a string from it like this
name: Jacket,price:300
name: Bag,price:650
name: Suit,price:300
What i did it gsub every needed element like gsub(':size=>','size:')
but it looks very ugly
Need more convenient solution for this
You could do something like:
Define a function on a hash to pretty print it for you.
map over the array to gain pretty printed strings for each.
def pretty_print(hash)
hash.map {|key, value| "#{key}: #{value}"}.join(', ')
end
arr.map {|hash| pretty_print(hash)}
If keys are predetermined:
arr.map { |item| "name:#{ item[:name] }, price:#{ item[:price] }" }.join("\n")
If not:
arr.map { |item| item.map { |k, v| "#{ k }:#{ v }" }.join(', ') }.join("\n")
Related
I am trying to access data that has a structure like this (the status of each user on specific dates). As you can see, the hash keys are all arrays. This data has been retrieved from the DB using group_by.
data = {
["active", "Rick"]=>["2019-07-09", "2019-07-10"],
["active", "Morty"]=>["2019-07-09", "2019-07-10"],
["active", "Summer"]=>["2019-07-09", "2019-07-10"],
["inactive", "Rick"]=> ["2019-07-01", "2019-07-02", "2019-07-03"],
["inactive", "Summer"]=>["2019-07-15"]
}
I would rather have this data be a nested hash, like below. Is there a way to restructure it?
I know that each item in the hash can be accessed like this: data[["active", "Summer"]]. I tried doing something like data[["active", "*"]] (to get the active status data for all users) but this did not work.
data = {
"active"=>{
"Rick"=>["2019-07-09", "2019-07-10"],
"Morty"=>["2019-07-09", "2019-07-10"],
"Summer"=>["2019-07-09", "2019-07-10"]
},
"inactive"=>{
"Rick"=>["2019-07-01", "2019-07-02", "2019-07-03"],
"Summer"=>["2019-07-15"]
}
}
This should work:
new_data = {}
data.each do |k, v|
new_data[k.first] ||= []
new_data[k.first] << { k.last => v}
end
But if you are in control of the db/query, perhaps it is better to retrieve your data from the db in the right format right away if possible.
You can do something like this -
new_data = { 'active' => [], 'inactive' => [] }
data.each do |key, value|
if key.first == 'active'
new_data['active'] << { key.last => value }
elsif key.first == 'inactive'
new_data['inactive'] << { key.last => value }
end
end
I have the following hash :
{
"2017-01-01" => {
"2"=> [
{:a=>"2017-01-01", :b=>"2", :c=>"1"},
{:a=>"2017-01-01", :b=>"2", :c=>"2"}
]
},
"2017-01-02" => {
"5"=> [
{:a=>"2017-01-02", :b=>"5", :c=>"1"}
]
}
}
I would iterate separately
1)first iteration
{
{:a=>"2017-01-01", :b=>"2", :c=>"1"},
{:a=>"2017-01-01", :b=>"2", :c=>"2"}
}
2) second iteration
{
{:a=>"2017-01-02", :b=>"5", :c=>"1"}
}
How can I do? Thanks in advance.
answer for your question is in How to iterate over a hash in Ruby?
check it.
hash.each do |key, array|
puts array
end
if 'array' again is a hash, then you need to loop it as follows
hash.each do |key, hash2|
hash2.each do |key2,array|
puts array
end
end
This is the code currently in auto_html.rb
The title needs to be dynamic, basically a full URL for a truncated URL where the truncated URL is generated by the auto_link.
AutoHtml.add_filter(:link).with({}) do |text, options|
attributes = Array(options).reject { |k,v| v.nil? }.map { |k, v| %{#{k}="#{REXML::Text::normalize(v)}"} }.join(' ')
Rinku.auto_link(text, :all, attributes) do |url|
url.gsub(/https?:\/\//, "").truncate(25)
end
end
You can add additional attributes as part of the string that gets passed into the third argument:
Rinku.auto_link(text, :all, 'title="my title" target="_blank"')
In your case you could just append it to the attributes variable:
AutoHtml.add_filter(:link).with({}) do |text, options|
attributes = Array(options).reject { |k,v| v.nil? }.map { |k, v| %{#{k}="#{REXML::Text::normalize(v)}"} }.join(' ')
attributes += ' title="My title"'
Rinku.auto_link(text, :all, attributes) do |url|
url.gsub(/https?:\/\//, "").truncate(25)
end
end
I have this hash:
h
=> {"67676.mpa"=>{:link=>"pool/sdafdsaff", :size=>4556}}
> h.each do |key, value|
> puts key
> puts value
> end
67676.mpa
linkpool/sdafdsaffsize4556
How do I access the separate values in the value hash on the loop?
Value is a Hash to so you need iterate on it or you can get only values:-
h.each do |key, value|
puts key
value.each do |k,v|
puts k
puts v
end
end
or
h.each do |key, value|
puts key
value.values.each do |v|
puts v
end
end
You'll want to recurse through the hash, here's a recursive method:
def ihash(h)
h.each_pair do |k,v|
if v.is_a?(Hash)
puts "key: #{k} recursing..."
ihash(v)
else
# MODIFY HERE! Look for what you want to find in the hash here
puts "key: #{k} value: #{v}"
end
end
end
You can Then take any hash and pass it in:
h = {
"x" => "a",
"y" => {
"y1" => {
"y2" => "final"
},
"yy1" => "hello"
}
}
ihash(h)
I little improved Travis's answer, how about this gist:
https://gist.github.com/kjakub/be17d9439359d14e6f86
class Hash
def nested_each_pair
self.each_pair do |k,v|
if v.is_a?(Hash)
v.nested_each_pair {|k,v| yield k,v}
else
yield(k,v)
end
end
end
end
{"root"=>{:a=>"tom", :b=>{:c => 1, :x => 2}}}.nested_each_pair{|k,v|
puts k
puts v
}
The simplest way to separate out all three values in this case would be as follows:
h.each do |key, value|
puts key
puts value[:link]
puts value[:size]
end
You can access the values of a hash directly by calling hash.values. In this case you could do something like
> h = {"67676.mpa"=>{:link=>"pool/sdafdsaff", :size=>4556}}
> h.values.each do |key, value|
> puts "#{key} #{value}"
> end
link pool/sdafsaff
size 4556
I have an each statement in a view:
<tr><% #quantity.each do |hash| %>
<td><%= hash.map { |key, value| "Channel: #{key} Quantity: #{value} units" } %>
</td><% end %></tr>
which is rendering on the webpage with square brackets and inverted commas, thus:
["Channel: 1 Quantity: 4675 units"]
["Channel: 2 Quantity: 2864 units"]
The array of hashes that it's looping round is this:
[{2=>2864}, {1=>4675}]
How do I stop the [" from showing up on the page?
Thanks!
map maps a hash into an array. The output is what it should be. Instead of using map, try:
#quantity.each do |hash|
hash.inspect
end
Should help.
Edit in response to your comment:
#quantity.each do |hash|
hash.each do |key, value|
"Key: #{key} Value: #{value}"
end
end