How to iterate over an array of hashes in Ruby and return all of the values of a specific key in a string
You can use Enumerable#map for this:
p foods.map { |f| f[:name] }
The code you tried to use did not produce any output or create any objects, and it was not necessary to use a second loop to access a single element of a hash.
Ruby iterate over an array of hashes
There is no need for the second loop. The following does what you want:
keys = stack[:all].map(&:to_sym)
keys.each do |key|
stack[key][:COUNT] = stack[key][:MAX_SIZE] * 2
end
In the above code-block stack[:all]
will return an array of keys as strings, .map(&:to_sym)
will convert each string in the resulting array into a symbol.
Another way to achieve the same result would be to use either fetch_values
or values_at
to retrieve an array of values belonging to the provided keys. The difference being that fetch_values
raises an exception if a key is missing while values_at
returns nil
for that key.
fruits = stack.fetch_values(*stack[:all].map(&:to_sym))
fruits.each do |fruit|
fruit[:COUNT] = fruit[:MAX_SIZE] * 2
end
If you are wondering why there is a *
before stack[:all].map(&:to_sym)
, this is to convert the array into individual arguments. In this context *
is called the spat operator.
How to iterate through an array of hashes in ruby
In newer versions of Ruby (not sure when it was introduced, probably around ruby 2.0-ish which is when I believe keyword arguments were introduced), you can do:
people.each do |salary:,**|
puts salary
end
where **
takes all the keyword arguments that you don't name and swallows them (ie, the first_name
and job_title
keys in the hash). If that isn't something that your ruby version allows, you'll need to just store the entire hash in the variable:
people.each do |person|
puts person[:salary]
end
iterate over an array of hashes to create data in rails
shoe_array
is an array of hashes, so you should iterate over each hash, and access each key-value pair:
shoe_array.each do |hash|
department_id = hash[:department_id]
follower_id = hash[:follower_id]
user_id = 1
Relationship.create!(
department_id: department_id,
follower_id: follower_id,
user_id: user_id
)
end
Loop through array of hash with a key containing an array
A simple approach is to just iterate both, array and product ids:
array.each do |hash|
hash[:product_ids].each do |product_id|
StoreExcludedProduct.create(
store_id: hash[:store_id],
product_id: product_id
)
end
end
You can wrap the above code in a transaction
call to avoid having separate transactions for each create
, i.e.:
StoreExcludedProduct.transaction do
array.each do |hash|
# ...
end
end
This also makes your code run in an all-or-nothing way.
Another option is insert_all
which can insert multiple records at once. In order to use it, you have to first build an array of attributes for each record, i.e. you have to split the product ids. This works a lot like the above code:
attributes = array.flat_map do |hash|
hash[:products_ids].map do |product_id|
{ store_id: hash[:store_id], product_id: product_id }
end
end
#=> [
# {:store_id=>5, :product_id=>1},
# {:store_id=>5, :product_id=>4},
# {:store_id=>5, :product_id=>19},
# {:store_id=>5, :product_id=>40},
# {:store_id=>13, :product_id=>2},
# #...
# ]
which can be passed to insert_all
:
StoreExcludedProduct.insert_all(attributes)
Note that this performs a raw SQL query without instantiating any models or running any callbacks or validations.
Get a value from an array of hashes in ruby
The select statement will return all the hashes with the key 13.
If you already know which hash has the key then the below code will give u the answer.
ary[1][13]
However if you are not sure which of your hashes in the array has the value, then you could do the following:
values = ary.map{|h| h[13]}.compact
Values will have the value of key 13 from all the hashes which has the key 13.
Iterate over array of hashes to sum values of one hash value based on another hash key
ar.
each_with_object({}) do |hash, acc|
(acc[hash["CustID"]] ||= {"Customer" => hash["CustID"], "TotalSales" => 0}).
tap { |h| h["TotalSales"] += hash["Sales"].to_f }
end.
values.
sort_by { |h| -h["TotalSales"] }.
map.
with_index(1) { |h, idx| h.merge("Rank" => idx) }
#⇒ [{"Customer"=>"Cust06", "TotalSales"=>2266.2925, "Rank"=>1},
# {"Customer"=>"Cust07", "TotalSales"=>2149.02, "Rank"=>2},
# {"Customer"=>"Cust08", "TotalSales"=>114.90699999999998, "Rank"=>3},
# {"Customer"=>"Cust04", "TotalSales"=>110.774, "Rank"=>4},
# {"Customer"=>"Cust09", "TotalSales"=>24.105, "Rank"=>5},
# {"Customer"=>"Cust02", "TotalSales"=>15.24, "Rank"=>6}]
Iterate an array of hashes
For your corrected data format:
@locations = { "cities"=>[
{ "longitude"=>-77.2497049,
"latitude"=>38.6581722,
"country"=>"United States",
"city"=>"Woodbridge, VA"},
{ "longitude"=>-122.697236,
"latitude"=>58.8050174,
"country"=>"Canada",
"city"=>"Fort Nelson, BC" }] }
@locations["cities"].each { |h| puts h["city"] }
Woodbridge, VA
Fort Nelson, BC
or to save in an array:
@locations["cities"].each_with_object([]) { |h,a| a << h["city"] }
#=> ["Woodbridge, VA", "Fort Nelson, BC"]
Related Topics
Implementation of "Remember Me" in a Rails Application
Adding Attributes to a Ruby Object Dynamically
How to Find the Source File for a Rake Task
Rspec: How to Test File Operations and File Content
Check If User Is Active Before Allowing User to Sign in with Devise (Rails)
Make Rake Task from Gem Available Everywhere
Undefined Method '>' for Nil:Nilclass <Nomethoderror>
Monkey-Patching VS. S.O.L.I.D. Principles
Phusion Passenger Error: You Have Activated Rack 1.2.1, But Your Gemfile Requires Rack 1.2.2
Rails-Like Database Migrations
Is It Idiomatic Ruby to Add an Assert( ) Method to Ruby's Kernel Class
How to Convert an Array of Strings into a Comma-Separated String
Count the Number of Lines in a File Without Reading Entire File into Memory
Bundler Install Getting "I18N Requires Ruby Version >= 1.9.3"