1

I'm trying to create a list of recipients to send in an external request by assigning it to a variable by doing the following:

recipients = @items.each do |item|
  {"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"},
end

but I'm getting this error:

syntax error, unexpected ',', expecting '}'

I know that what I've done is not the right syntax. I'm kind of a Ruby newbie, so can someone help me figure out the correct syntax here?

EDIT: Thanks for the input. But what if I need to do two hashes for each item?

recipients = @items.map do |item|
  {"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"},
  {"email"=>"#{Store.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
end
1
  • try removing the , at the end of the hash declaration. Commented Jan 14, 2012 at 5:04

2 Answers 2

3

The problem is with the comma at the end of the hash. Also if you want to store the email and amount in recipients, you should use map. This will return an array of hash with email and amount:

recipients = @items.map do |item|
  {"email"=> Recipient.find_by_id(item.recip_id).email, "amount"=> item.price}
end

Also, as you might note, I don't need to pass the values of email and prices as a string.

Sign up to request clarification or add additional context in comments.

6 Comments

Ok thanks. But what if I need to do two hashes for each item (i.e. two email - amount pairs)? I've put an example in the question. Sorry - I realize I hadn't asked this before, but I recently realized I need two hashes for each item.
@varatis: You could return a two element array from your map block and then flatten the result or switch to each_with_object([]) and push your two entries onto the array inside the block.
The problem with using hash is that they will need a unique key. So the key email can have only one value key. One way would be to use an hash of hash. Something like {"1" => {"email" => "abc", "amount" => "xyz"}, "2" => {"email" => "pqr", "amount" => "lmn"}}, where 1 and 2 can be the id's of items.
@WahajAli So there is no way to just make a simple array of hashes like [{"email" => email1, "amount"=> item1}, {"email" => email2, "amount" => item2}, ....]? I don't know why you'd need to make each entry have different keys.
Yes, sorry, I seem to have misunderstood your comment. I meant you could not have multiple keys with the same name in a single hash. What you wrote would work perfectly.
|
1

If you want to return multiple hashes from your map block then you'd be better off switching to each_with_object:

Iterates the given block for each element with an arbitrary object given, and returns the initially given object.

So something like this:

recipients = @items.each_with_object([]) do |item, a|
  a << {"email"=>"#{Recipient.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
  a << {"email"=>"#{Store.find_by_id(item.recip_id).email}", "amount"=>"#{item.price}"}
end

2 Comments

Ah! This finally solves it. I assume the << operator appends the hash to a?
@varatis: Yes, Array#<< is the same as Array#push.

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.