0

I've created the following hash keys with values parsed from PDF into array:

columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
h = Hash[columns.map.with_index.to_h]
=> {"Sen"=>0, "P-Hire#"=>1, "Emp#"=>2, "DOH"=>3, "Last"=>4, "First"=>5}

Now I want to update the value of each key with 6 equivalent values from another parsed data array:

rows = list.text.scan(/^.+/)
row = rows[0].tr(',', '')
@data = row.split
=> ["2", "6", "239", "05/05/67", "Harp", "Erin"]

I can iterate over @data in the view and it will list each of the 6 values. When I try to do the same in the controller it sets the same value to each key:

data.each do |e|
  h.update(h){|key,v1| (e) }
end
=>
{"Sen"=>"Harper", "P-Hire#"=>"Harper", "Emp#"=>"Harper", "DOH"=>"Harper", "Last"=>"Harper", "First"=>"Harper"

So it's setting the value of each key to the last value of the looped array...

2
  • What do you want the resulting hash to look like? Commented Apr 1, 2017 at 0:11
  • 1
    FYI: Hash[....to_h] is redundant. You can drop the Hash[], it's not doing anything, columns.map.with_index.to_h is giving you the value you're after. Commented Apr 1, 2017 at 0:18

2 Answers 2

4

I would just do:

h.keys.zip(@data).to_h

If the only purpose of h is as an interim step getting to the result, you can dispense with it and do:

columns.zip(@data).to_h
Sign up to request clarification or add additional context in comments.

5 Comments

Perfect! Thanks for the help! Remarkably useful method. It's not listed in the online docs I was using so thanks for the knowledge.
This answer, imo, should have received the ✅.
@CarySwoveland - I agree. It has been changed.
This worked by supplying a single object row = rows[0].tr(',', '').split but when trying to loop through them with rows.each, the .split method fails which in turn causes the zip().to_h to also fail. Any ideas?
You'll need to provide more information. Please submit a new question with a detailed explanation of the setup and the error you are getting.
1

There are several ways to solve this problem but a more direct and straight forward way would be:

columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
...
@data = row.split

h = Hash.new
columns.each_with_index do |column, index|
 h[column] = @data[index]
end

Another way:

h.each do |key, index|
  h[key] = @data[index]
end

Like I said, there are several ways of solving the issue and the best is always going to depend on what you're trying to achieve.

3 Comments

Ruby convention is to avoid each (and indexes) when other methods can achieve the same result.
yes, you're right. But I'd rather also prefer explicitness over hidden abstractions
I'm all for explicitness, but how is zip more hidden or abstract than index or each? This seems to be precisely the use case for zip followed by to_h.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.