One of my tables has a recurring column name / type id, description, ...., day1, day2, day3 ... day7 inside each of the days is an int. Currently, I''m using send to loop over the day columns total = 0 7.times do |i| total += row.send("day" + (i+1).to_s) end I don''t know how (in)efficient this is. Does anyone know a better way? Also I was reading something about {} last night and it looks like I could write this as total = 0 7.times do |i| { total += row.send("day" + (i+1).to_s) } They both are pretty legible to me, but is there a major convention I should follow? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Also I was reading something about {} last night and it looks like I > could write this as > > total = 0 > 7.times do |i| { total += row.send("day" + (i+1).to_s) } > > They both are pretty legible to me, but is there a major convention I > should follow?How about: total = 0 1.upto(7) { |i| total += row.send("day#{i}") } -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 15:20 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Alex Treber wrote:> > One of my tables has a recurring column name / type > > id, description, ...., day1, day2, day3 ... day7 > > inside each of the days is an int. > > Currently, I''m using send to loop over the day columns > > total = 0 > 7.times do |i| > total += row.send("day" + (i+1).to_s) > end > > I don''t know how (in)efficient this is. Does anyone know a better way? > > Also I was reading something about {} last night and it looks like I > could write this as > > total = 0 > 7.times do |i| { total += row.send("day" + (i+1).to_s) } > > They both are pretty legible to me, but is there a major convention I > should follow?This kind of summing is often done with inject. Here''s a[n untested] example: total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } The idea is that the code block is run seven times, with an accumulator and the current day-number as arguments. The accumulator''s value the first time through is 0. Each time through, the block returns the sum of the accumulator and the row''s value for the current day. That value is then used as the value for the accumulator the next time through. So by the seventh time, it''s returning the sum of all of them -- and that''s the final value of the whole inject expression, which then gets assigned to total. David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Luke wrote:> total = 0 > 1.upto(7) { |i| total += row.send("day#{i}") }Ah, I like that a lot better. So send is the way to go. Does the #{i} format work with arrays as well? value[:d1] - value[:d7] could be value[:d#{i}]? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi,>> Also I was reading something about {} last night and it looks like I >> could write this as >> >> total = 0 >> 7.times do |i| { total += row.send("day" + (i+1).to_s) } >> >> They both are pretty legible to me, but is there a major convention I >> should follow? >> > > How about: > > total = 0 > 1.upto(7) { |i| total += row.send("day#{i}") } > >How about a one-liner? total = (1..7).inject {|sum, i| sum + row.send "day#{i}"} Docs on inject: http://ruby-doc.org/core/classes/Enumerable.html#M003176 Cheers! Patrick --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote:> Hi -- > > On Tue, 9 Jan 2007, Alex Treber wrote: > > >> One of my tables has a recurring column name / type >> >> id, description, ...., day1, day2, day3 ... day7 >> >> inside each of the days is an int. >> >> Currently, I''m using send to loop over the day columns >> >> total = 0 >> 7.times do |i| >> total += row.send("day" + (i+1).to_s) >> end >> >> I don''t know how (in)efficient this is. Does anyone know a better way? >> >> Also I was reading something about {} last night and it looks like I >> could write this as >> >> total = 0 >> 7.times do |i| { total += row.send("day" + (i+1).to_s) } >> >> They both are pretty legible to me, but is there a major convention I >> should follow? >> > > This kind of summing is often done with inject. Here''s a[n untested] > example: > > total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } > > The idea is that the code block is run seven times, with an > accumulator and the current day-number as arguments. The > accumulator''s value the first time through is 0. Each time through, > the block returns the sum of the accumulator and the row''s value for > the current day. That value is then used as the value for the > accumulator the next time through. > > So by the seventh time, it''s returning the sum of all of them -- and > that''s the final value of the whole inject expression, which then gets > assigned to total. >Argh, beat me by a couple minutes David :) Much better explanation though... but isn''t inject(0) redundant? Just inject {} does the trick because nil.to_i is 0... Cheers! Patrick --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Alex Treber wrote:> Luke wrote: > >> total = 0 >> 1.upto(7) { |i| total += row.send("day#{i}") } >> > > Ah, I like that a lot better. So send is the way to go. > > Does the #{i} format work with arrays as well? value[:d1] - value[:d7] > could be value[:d#{i}]? > > >The #{i} format works in double quoted strings and does not work with symbols. If the keys for value were ''d1'', ''d2'', etc. (strings) instead of :d1, :d2 (symbols), then you could use value["d#{i}] --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> total = (1..7).inject {|sum, i| sum + row.send "day#{i}"}Learn something new every day - cheers David/Patrick! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> Does the #{i} format work with arrays as well? value[:d1] - value[:d7] > could be value[:d#{i}]?Someone else might want to comment on this but as far as I know it will only be replaced in double-quoted strings i.e. "#{var}" You could do value[:"d#{i}"] but I''m not sure on the value of that. I think there is a method that will convert a string to a :param but I cant remember what its called. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
> total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") }Just looking this over, it sort of makes sense, but could you expand on this a little more? (1..7).inject - number of times run, start and end values (0) - initial value {|acc, - the internal variable that is assigned the init value day|} - ? not sure about is there, should it be i? acc + ... } - the code that is executed Perhaps I am making a leap here but if these are the same Davids -> David > A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)I''ve been working through your book lately. It''s been very helpful and enlightening! Thanks for taking the time to write it. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 15:48 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Patrick Ritchie wrote:> dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote: >> Hi -- >> >> On Tue, 9 Jan 2007, Alex Treber wrote: >> >> >>> One of my tables has a recurring column name / type >>> >>> id, description, ...., day1, day2, day3 ... day7 >>> >>> inside each of the days is an int. >>> >>> Currently, I''m using send to loop over the day columns >>> >>> total = 0 >>> 7.times do |i| >>> total += row.send("day" + (i+1).to_s) >>> end >>> >>> I don''t know how (in)efficient this is. Does anyone know a better way? >>> >>> Also I was reading something about {} last night and it looks like I >>> could write this as >>> >>> total = 0 >>> 7.times do |i| { total += row.send("day" + (i+1).to_s) } >>> >>> They both are pretty legible to me, but is there a major convention I >>> should follow? >>> >> >> This kind of summing is often done with inject. Here''s a[n untested] >> example: >> >> total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } >> >> The idea is that the code block is run seven times, with an >> accumulator and the current day-number as arguments. The >> accumulator''s value the first time through is 0. Each time through, >> the block returns the sum of the accumulator and the row''s value for >> the current day. That value is then used as the value for the >> accumulator the next time through. >> >> So by the seventh time, it''s returning the sum of all of them -- and >> that''s the final value of the whole inject expression, which then gets >> assigned to total. >> > Argh, beat me by a couple minutes David :) Much better explanation > though... but isn''t inject(0) redundant? Just inject {} does the trick > because nil.to_i is 0...It does default to 0, though I don''t think it''s because of nil.to_i, since that implies that there''s an automatic to_i performed on the accumulator, which there isn''t; you can do: [1,2,3].inject([]) ... for example. I usually put the 0 in anyway just because it''s sort of self-documenting that way. David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 15:50 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Daniel Higginbotham wrote:> > Alex Treber wrote: >> Luke wrote: >> >>> total = 0 >>> 1.upto(7) { |i| total += row.send("day#{i}") } >>> >> >> Ah, I like that a lot better. So send is the way to go. >> >> Does the #{i} format work with arrays as well? value[:d1] - value[:d7] >> could be value[:d#{i}]? >> >> >> > The #{i} format works in double quoted strings and does not work with > symbols. If the keys for value were ''d1'', ''d2'', etc. (strings) instead > of :d1, :d2 (symbols), then you could use value["d#{i}]To get a symbol while taking advantage of string interpolation you could also do: value[:"d#{i}"] David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Here is hopefully my last tangent for the thread. What if I wanted to assign a value dynamically? cell = returnEditedCell(params) row.send("day#{cell}") = newVal 211: syntax error, unexpected ''='', expecting kEND row.send("day#{cell}") = values[:"d#{cell}"].to_f And Luke had it right, I was missing the ""s from the array call, so value[:"d#(i)"] worked. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 15:56 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Alex Treber wrote:>> total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } > > Just looking this over, it sort of makes sense, but could you expand on > this a little more? > > (1..7).inject - number of times run, start and end valuesAnd it can be any Enumerable (array, range, hash, string, your own, etc.).> (0) - initial value > {|acc, - the internal variable that is assigned the init value > day|} - ? not sure about is there, should it be i? > acc + ... } - the code that is executedYes, you''re right: day should be i in the block variable list. I got too cutesy with the variable names. Once again the ''untested'' disclaimer comes to the rescue :-) Does that answer all your questions? If not, let me know.> Perhaps I am making a leap here but if these are the same Davids - >> David >> A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)It''s a pretty logical leap, and a correct one :-)> I''ve been working through your book lately. It''s been very helpful and > enlightening! Thanks for taking the time to write it.Thanks -- glad to have done it! David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 16:01 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Alex Treber wrote:> Here is hopefully my last tangent for the thread. > > What if I wanted to assign a value dynamically? > > cell = returnEditedCell(params) > > row.send("day#{cell}") = newVal > > 211: syntax error, unexpected ''='', expecting kEND > row.send("day#{cell}") = values[:"d#{cell}"].to_fThe missing ingredient here is the fact that day1=, day2=, etc. are actually names of methods (assuming we''re still talking about those). So you have to send the whole thing, plus any arguments, like this (untested): row.send("day#{cell}=", values[:"d#{cell}"].to_f) I''ve sort of lost track of exactly what kind of object we''re dealing with here, but there might be other things you can do involving addressing attributes directly. But that''s the basic deal with the send semantics. David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote:> Hi -- > > On Tue, 9 Jan 2007, Patrick Ritchie wrote: > > >> dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote: >> >>> Hi -- >>> >>> On Tue, 9 Jan 2007, Alex Treber wrote: >>> >>> >>> >>>> One of my tables has a recurring column name / type >>>> >>>> id, description, ...., day1, day2, day3 ... day7 >>>> >>>> inside each of the days is an int. >>>> >>>> Currently, I''m using send to loop over the day columns >>>> >>>> total = 0 >>>> 7.times do |i| >>>> total += row.send("day" + (i+1).to_s) >>>> end >>>> >>>> I don''t know how (in)efficient this is. Does anyone know a better way? >>>> >>>> Also I was reading something about {} last night and it looks like I >>>> could write this as >>>> >>>> total = 0 >>>> 7.times do |i| { total += row.send("day" + (i+1).to_s) } >>>> >>>> They both are pretty legible to me, but is there a major convention I >>>> should follow? >>>> >>>> >>> This kind of summing is often done with inject. Here''s a[n untested] >>> example: >>> >>> total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } >>> >>> The idea is that the code block is run seven times, with an >>> accumulator and the current day-number as arguments. The >>> accumulator''s value the first time through is 0. Each time through, >>> the block returns the sum of the accumulator and the row''s value for >>> the current day. That value is then used as the value for the >>> accumulator the next time through. >>> >>> So by the seventh time, it''s returning the sum of all of them -- and >>> that''s the final value of the whole inject expression, which then gets >>> assigned to total. >>> >>> >> Argh, beat me by a couple minutes David :) Much better explanation >> though... but isn''t inject(0) redundant? Just inject {} does the trick >> because nil.to_i is 0... >> > > It does default to 0, though I don''t think it''s because of nil.to_i, > since that implies that there''s an automatic to_i performed on the > accumulator, which there isn''t; you can do: > > [1,2,3].inject([]) ... > > for example. > > I usually put the 0 in anyway just because it''s sort of > self-documenting that way. >Should have read the docs better: > enum.inject(initial) {| memo, obj | block } => obj > enum.inject {| memo, obj | block } => obj > > The second form uses the first element of the collection as a the > initial value (and skips that element while iterating). So in the following the block is only called *once*: [1, 2].inject {|sum, i| "sum:#{sum} i:#{i}"} # => sum:1 i:2 This also means we need to specify the 0 in the original case or we will never get the actual value for day 1. Cheers! Patrick --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Alex,> What if I wanted to assign a value dynamically? > > cell = returnEditedCell(params) > > row.send("day#{cell}") = newValnot tested but it should be : row.send("day#{cell}=", newVal) or row.write_attribute("day#{cell}", newVal) or row[ :"day#{cell} ] = newVal> 211: syntax error, unexpected '=', expecting kEND > row.send("day#{cell}") = values[:"d#{cell}"].to_fIn fact, you want to use the method day1=, day2= ... and not day1, day2. -- Jean-François. -- À la renverse. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk@googlegroups.com To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
not to knock the inject way being discussed (i like inject, honest!) but there is a bit of a penalty for using an iterator versus just adding up the respective totals. since you know you only have the 7 columns in your record so why not just total them up within the model as an alternative? unless you plan on adding day columns to your table, the method should never change. class MyModel < ActiveRecord::Base def day_total day1 + day2 + day3 + day4 + day5 + day6 + day7 end end a quick test of inject vs unrolled shows (using the day1..day7 method described previously vs. day_total method described here) 10000 iterations inject: 0.568689000000041 unrolled: 0.119564999999983 diff: 0.449124000000058 on average, thats about a 1/2 sec difference on 10000 records. i know that''s not a lot but it can make a difference when you have a reporting system and everyone wants their reports at month end! :) anyways, thats my $0.02 on the subject. On 1/9/07, dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org <dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org> wrote:> > Hi -- > > On Tue, 9 Jan 2007, Alex Treber wrote: > > >> total = (1..7).inject(0) {|acc,day| acc + row.send("day#{i}") } > > > > Just looking this over, it sort of makes sense, but could you expand on > > this a little more? > > > > (1..7).inject - number of times run, start and end values > > And it can be any Enumerable (array, range, hash, string, your own, > etc.). > > > (0) - initial value > > {|acc, - the internal variable that is assigned the init value > > day|} - ? not sure about is there, should it be i? > > acc + ... } - the code that is executed > > Yes, you''re right: day should be i in the block variable list. I got > too cutesy with the variable names. Once again the ''untested'' > disclaimer comes to the rescue :-) > > Does that answer all your questions? If not, let me know. > > > Perhaps I am making a leap here but if these are the same Davids - > >> David > >> A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) > > It''s a pretty logical leap, and a correct one :-) > > > I''ve been working through your book lately. It''s been very helpful and > > enlightening! Thanks for taking the time to write it. > > Thanks -- glad to have done it! > > > David > > -- > Q. What is THE Ruby book for Rails developers? > A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) > (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) > Q. Where can I get Ruby/Rails on-site training, consulting, coaching? > A. Ruby Power and Light, LLC (http://www.rubypal.com) > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org
2007-Jan-09 21:03 UTC
Re: Better way to do this?
Hi -- On Tue, 9 Jan 2007, Patrick Ritchie wrote:> dblack-TKXtfPMJ4Ozk1uMJSBkQmQ@public.gmane.org wrote: >> >> It does default to 0, though I don''t think it''s because of nil.to_i, >> since that implies that there''s an automatic to_i performed on the >> accumulator, which there isn''t; you can do: >> >> [1,2,3].inject([]) ... >> >> for example. >> >> I usually put the 0 in anyway just because it''s sort of >> self-documenting that way. >> > Should have read the docs better: > > > enum.inject(initial) {| memo, obj | block } => obj > > enum.inject {| memo, obj | block } => obj > > > > The second form uses the first element of the collection as a the > > initial value (and skips that element while iterating). > > So in the following the block is only called *once*: > > [1, 2].inject {|sum, i| "sum:#{sum} i:#{i}"} # => sum:1 i:2 > > This also means we need to specify the 0 in the original case or we will > never get the actual value for day 1.So my instincts were right, but for the wrong reason :-) Thanks for the clarifying quote from the docs. Interesting that in most of the inject cases one sees, the 0-default theory sort of works by coincidence: if you''re summing an array of numbers, the first one gets used as the basis anyway, and added to from then on; and most of the time that you''re *not* using numbers, the seed value matters so you usually see one: ["a","b","c"].inject([]) {|arr,s| arr << s.upcase } # ["A","B","C"] ["a","b","c"].inject {|arr,s| arr << s.upcase } # "aBC" (Not a great real-world example, but anyway.) David -- Q. What is THE Ruby book for Rails developers? A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black) (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf) Q. Where can I get Ruby/Rails on-site training, consulting, coaching? A. Ruby Power and Light, LLC (http://www.rubypal.com) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I would point out that the "official" way to do this is with associations: has_many :days You can then do everything you wanted quite easily. (This is actually part of normal form, which are key principles of database design) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---