The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Ruby Programming
|
Rails - Iterating through nested arrays
Discuss Rails - Iterating through nested arrays in the Ruby Programming forum on Dev Shed. Rails - Iterating through nested arrays Ruby and Ruby on Rails programming forum covering Ruby Tips and Tricks, Best Practices, and agile development with Ruby on Rails.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

October 11th, 2010, 04:31 PM
|
|
Registered User
|
|
Join Date: Sep 2010
Posts: 6
Time spent in forums: 1 h 11 m
Reputation Power: 0
|
|
|
Rails - Iterating through nested arrays
Hi I'm very new to rails and need some help on iterating through nested arrays. I'm trying to figure out how to do mass-inserts for each values that is different between the make, model and color of cars.
The params that are pass are:
"make" => ["Honda", "Honda"],
"model" => ["Civic", "Accord"],
"color" => [{"Black", "White", "Red"}, {"Black", "White"}]
So with these params passed, I wanted to have 5 inserts to occur.
1. Civic - Black
2. Civic - White
3. Civic - Red
4. Accord - Black
5. Accord - White
Here what I've got so far that pushes the insert query that builds it. But I'm unsure how to make it insert 5 times according to what I've listed above:
Code:
def self.cars(make, model, color)
inserts = []
color.each do |i|
inserts.push "('#{make}', '#{model}', '#{i}')"
end
Foo.connection.execute "INSERT INTO car_inventory (make, model, color) VALUES #{inserts.join(", ")}"
end
Please help.
|

October 11th, 2010, 05:08 PM
|
|
Contributing User
|
|
Join Date: Jan 2004
Location: Constant Limbo
|
|
Arrays have a method called each_with_index which is what it looks like you want. Consider the following:
Code:
irb(main):001:0> make = ["honda", "honda"]
=> ["honda", "honda"]
irb(main):002:0> model = ["civic", "accord"]
=> ["civic", "accord"]
irb(main):003:0> color = [["black", "white", "red"], ["black", "white"]]
=> [["black", "white", "red"], ["black", "white"]]
irb(main):004:0> make.uniq.each do |mk|
irb(main):005:1* model.each_with_index do |mdl, idx|
irb(main):006:2* color[idx].each do |col|
irb(main):007:3* puts "#{mk}:#{mdl}:#{col}"
irb(main):008:3> end
irb(main):009:2> end
irb(main):010:1> end
honda:civic:black
honda:civic:white
honda:civic:red
honda:accord:black
honda:accord:white
__________________
True happiness is not getting what you want, it's wanting what you've already got.
My Blog
|

October 11th, 2010, 10:18 PM
|
|
Registered User
|
|
Join Date: Sep 2010
Posts: 6
Time spent in forums: 1 h 11 m
Reputation Power: 0
|
|
L7Sqr, Thanks for the reply, which helps me understand this better. But let's say my form (using form_for) has 3 checkboxes for Black, White, and Red. With all the colors checked, the values are loaded into mass-assignment called 'car' as shown below:
Code:
"car"=>{"make"=>"Honda", "color"=>["0", "Black", "0", "White", "0", "Red"], "model"=>"Accord", "tinted"=>"yes"}}
(Not sure why the check_box helper puts '0' along with the values but I'm sure I can place a conditional to work around that.)
So with that mass-assignment, is it possible to put some code in the model that iterates through each color and does 3 inserts?
|

October 12th, 2010, 05:01 AM
|
|
Contributing User
|
|
Join Date: Jan 2004
Location: Constant Limbo
|
|
Code:
irb(main):001:0> hash = {}
=> {}
irb(main):002:0> hash["car"] = {"make"=>"Honda", "color"=>["0", "Black", "0", "White", "0", "Red"], "model"=>"Accord", "tinted"=>"yes"}
=> {"model"=>"Accord", "tinted"=>"yes", "color"=>["0", "Black", "0", "White", "0", "Red"], "make"=>"Honda"}
irb(main):003:0> car = hash["car"]
=> {"model"=>"Accord", "tinted"=>"yes", "color"=>["0", "Black", "0", "White", "0", "Red"], "make"=>"Honda"}
irb(main):004:0> make = car["make"]
=> "Honda"
irb(main):005:0> model = car["model"]
=> "Accord"
irb(main):006:0> colors = car["color"]
=> ["0", "Black", "0", "White", "0", "Red"]
irb(main):007:0> [1,3,5].each do |i|
irb(main):008:1* puts "(#{make}, #{model}, #{colors[i]})"
irb(main):009:1> end
(Honda, Accord, Black)
(Honda, Accord, White)
(Honda, Accord, Red)
=> [1, 3, 5]
irb(main):010:0>
What you'd like to do is convert the color array into a hash but the order of the elements prevents that directly due to multiple assignments to the same key. For instance
Code:
irb(main):001:0> colors = ["0", "Black", "0", "White", "0", "Red"]
=> ["0", "Black", "0", "White", "0", "Red"]
irb(main):002:0> Hash[*colors]
=> {"0"=>"Red"}
irb(main):003:0> colors = ["Black", "0", "White", "0", "Red", "0"]
=> ["Black", "0", "White", "0", "Red", "0"]
irb(main):004:0> Hash[*colors]
=> {"Black"=>"0", "Red"=>"0", "White"=>"0"}
irb(main):005:0>
Which is why I used the array of 1, 3, 5 to index the color values. This is brittle and as you add colors this will break. The best way to do that is to convert the color array to an appropriate structure and iterate through that directly.
|

October 12th, 2010, 03:07 PM
|
|
Registered User
|
|
Join Date: Sep 2010
Posts: 6
Time spent in forums: 1 h 11 m
Reputation Power: 0
|
|
Quote: | Originally Posted by L7Sqr
Code:
irb(main):001:0> hash = {}
=> {}
irb(main):002:0> hash["car"] = {"make"=>"Honda", "color"=>["0", "Black", "0", "White", "0", "Red"], "model"=>"Accord", "tinted"=>"yes"}
=> {"model"=>"Accord", "tinted"=>"yes", "color"=>["0", "Black", "0", "White", "0", "Red"], "make"=>"Honda"}
irb(main):003:0> car = hash["car"]
=> {"model"=>"Accord", "tinted"=>"yes", "color"=>["0", "Black", "0", "White", "0", "Red"], "make"=>"Honda"}
irb(main):004:0> make = car["make"]
=> "Honda"
irb(main):005:0> model = car["model"]
=> "Accord"
irb(main):006:0> colors = car["color"]
=> ["0", "Black", "0", "White", "0", "Red"]
irb(main):007:0> [1,3,5].each do |i|
irb(main):008:1* puts "(#{make}, #{model}, #{colors[i]})"
irb(main):009:1> end
(Honda, Accord, Black)
(Honda, Accord, White)
(Honda, Accord, Red)
=> [1, 3, 5]
irb(main):010:0>
What you'd like to do is convert the color array into a hash but the order of the elements prevents that directly due to multiple assignments to the same key. For instance
Code:
irb(main):001:0> colors = ["0", "Black", "0", "White", "0", "Red"]
=> ["0", "Black", "0", "White", "0", "Red"]
irb(main):002:0> Hash[*colors]
=> {"0"=>"Red"}
irb(main):003:0> colors = ["Black", "0", "White", "0", "Red", "0"]
=> ["Black", "0", "White", "0", "Red", "0"]
irb(main):004:0> Hash[*colors]
=> {"Black"=>"0", "Red"=>"0", "White"=>"0"}
irb(main):005:0>
Which is why I used the array of 1, 3, 5 to index the color values. This is brittle and as you add colors this will break. The best way to do that is to convert the color array to an appropriate structure and iterate through that directly. |
Would you know the Rails way of making this work so that the values are inserted into the db 3 times at once?
|

October 12th, 2010, 05:44 PM
|
|
Contributing User
|
|
Join Date: Jan 2004
Location: Constant Limbo
|
|
|
I would not. Rails is a framework built on top of Ruby and I've neither needed nor bothered to learn it. However, under the interface, you are going to be iterating over an enumeration of values and joining them somehow to make your SQL statements.
There are people here who have used rails more than myself and maybe they will assist - if not you can start to look at how things are done by digging through the code.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|