|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I'm not sure how I feel about inject's pathological case. What do you
all think should happen in the following code? [2].inject {|a, i| puts i} I might have thought that the block would never be called and the method would return 2. If the block must be called, I might expect "i" to be nil. What actually happens is that the block is called and "i" is the same thing as "a". I did not expect this and I'm trying to figure out how this is either consistent or useful. Can someone clue me in to this behaviour? Thank you... |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Just Another Victim... wrote:
> I'm not sure how I feel about inject's pathological case. What do you > all think should happen in the following code? > > > [2].inject {|a, i| puts i} > > > I might have thought that the block would never be called and the > method > would return 2. > If the block must be called, I might expect "i" to be nil. > What actually happens is that the block is called and "i" is the > same > thing as "a". I did not expect this and I'm trying to figure out how > this > is either consistent or useful. Can someone clue me in to this > behaviour? I'm not seeing that: 1) Two element array: result = [2, 3].inject do |a, i| puts "a:#{a}" puts "i:#{i}" puts "hello" puts "--------" end puts "result=#{result}" if result.nil? puts 'yes' end --output:-- a:2 i:3 hello -------- result= yes 2) One element array: result = [2].inject do |a, i| puts "a:#{a}" puts "i:#{i}" puts "hello" puts "--------" end puts "result=#{result}" if result.nil? puts 'yes' end --output:-- result=2 -- Posted via http://www.ruby-forum.com/. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Oh, yeah:
$ ruby -v ruby 1.8.2 (2004-12-25) [universal-darwin8.0] By the way, using inject() is inefficient--not to mention confusing. You might as well pretend it doesn't exist. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Hi --
On Sun, 30 Mar 2008, Just Another Victim of the Ambient Morality wrote: > I'm not sure how I feel about inject's pathological case. What do you > all think should happen in the following code? > > > [2].inject {|a, i| puts i} > > > I might have thought that the block would never be called and the method > would return 2. > If the block must be called, I might expect "i" to be nil. > What actually happens is that the block is called and "i" is the same > thing as "a". I did not expect this and I'm trying to figure out how this > is either consistent or useful. Can someone clue me in to this behaviour? > Thank you... Actually the block isn't being called: irb(main):005:0> [2].inject {|a, i| puts "hi" } => 2 irb(main):006:0> [2].inject {} => 2 The value of the whole statement is 2, or, more generally, the first (and only) element in the enumerable. I guess that's all it can do since it doesn't have enough elements to call the block even once. David -- Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS April 14-17 New York City INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin See http://www.rubypal.com for details and updates! |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
David A. Black wrote:
> > Actually the block isn't being called: > I guess that's all it can do > since it doesn't have enough elements to call the block even once. > To add to that, on p.456 of pickaxe2 it says that if you don't supply an argument for the inject call, then the first element in the enumerable becomes 'a', and it is not included in subsequent iteration. Apparently, because there are no values to iterate over, the block does not execute. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Mar 30, 12:27 am, 7stud -- <bbxx789_0...@yahoo.com> wrote:
> Oh, yeah: > > $ ruby -v > ruby 1.8.2 (2004-12-25) [universal-darwin8.0] > > By the way, using inject() is inefficient--not to mention confusing. > You might as well pretend it doesn't exist. There is some truth to that. def collect_repeats_inject list return [] if [] == list list[1..-1].inject([[ list.first ]]){|a,e| if a[-1][0] == e a[-1] << e else a << [e] end a }.reject{|lst| lst.size < 2 } end def collect_repeats list accum = [ [ list.shift ] ] list.each{|e| if accum[-1][0] == e accum[-1] << e else accum << [e] end } accum.reject{|lst| lst.size < 2 } end p collect_repeats( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) p collect_repeats( [] ) p collect_repeats_inject( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) p collect_repeats_inject( [] ) the_list = %w(0 1 1 2 3 3 3 3 3 3 3 3 4 5 5 6 7 8 8 9 9 9) t = Time.now 9999.times{ collect_repeats_inject( the_list )} p Time.now - t t = Time.now 9999.times{ collect_repeats( the_list )} p Time.now - t --- output --- [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] [] [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] [] 2.694 0.16 And the version without inject is shorter and clearer. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Mar 30, 12:27 am, 7stud -- <bbxx789_0...@yahoo.com> wrote:
> Oh, yeah: > > $ ruby -v > ruby 1.8.2 (2004-12-25) [universal-darwin8.0] > > By the way, using inject() is inefficient--not to mention confusing. > You might as well pretend it doesn't exist. There is some truth to that. def collect_repeats_inject list return [] if [] == list list[1..-1].inject([[ list.first ]]){|a,e| if a[-1][0] == e a[-1] << e else a << [e] end a }.reject{|lst| lst.size < 2 } end def collect_repeats list return [] if [] == list accum = [ [ list.first ] ] list[1..-1].each{|e| if accum[-1][0] == e accum[-1] << e else accum << [e] end } accum.reject{|lst| lst.size < 2 } end p collect_repeats( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) p collect_repeats( [] ) p collect_repeats_inject( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) p collect_repeats_inject( [] ) the_list = %w(0 1 1 2 3 3 3 3 3 3 3 3 4 5 5 6 7 8 8 9 9 9) t = Time.now 9999.times{ collect_repeats_inject( the_list )} p Time.now - t t = Time.now 9999.times{ collect_repeats( the_list )} p Time.now - t --- output --- [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] [] [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] [] 2.814 1.923 And the version without inject seems clearer. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On 3/30/08, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> By the way, using inject() is inefficient--not to mention confusing. > You might as well pretend it doesn't exist. Or much better, understand that it's a way to reduce/fold the elements of an enumerable into a single value. http://en.wikipedia.org/wiki/Fold_%2...er_function%29 Enumerable#inject is very useful, as long as you don't treat it as Maslow's hammer and use it in inappropriate ways, such as giving it a block like in the original posting to this thread. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/ |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
> Understand that it's a way to reduce/fold the elements
> of an enumerable into a single value. Not that this is important, but personally I never liked the name inject Though fold(l/r) is not much better either. A peculiar thing is that the wikipedia page gives "also known variously as " four different names as alternative/example. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On Sun, Mar 30, 2008 at 3:34 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:
> On 3/30/08, 7stud -- <bbxx789_05ss@yahoo.com> wrote: > > > By the way, using inject() is inefficient--not to mention confusing. > > You might as well pretend it doesn't exist. > > Or much better, understand that it's a way to reduce/fold the elements > of an enumerable into a single value. > http://en.wikipedia.org/wiki/Fold_%2...er_function%29 > > Enumerable#inject is very useful, as long as you don't treat it as > Maslow's hammer and use it in inappropriate ways, such as giving it a > block like in the original posting to this thread. > > -- > Rick DeNatale > > My blog on Ruby > http://talklikeaduck.denhaven2.com/ > > Completely agree with Rick and furthermore you will not be able to understand Ruby code written by others if you do not have a basic understanding of inject. I found this code in Ruby1.9 though if result.size > 0 and result.inject(false) {|k,s| s or k} that kind of code explains why inject has a bad reputation. Cheers Robert -- http://ruby-smalltalk.blogspot.com/ --- Whereof one cannot speak, thereof one must be silent. Ludwig Wittgenstein |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
On Sun, Mar 30, 2008 at 10:30 AM, Marc Heiler <shevegen@linuxmail.org> wrote:
> > Understand that it's a way to reduce/fold the elements > > of an enumerable into a single value. > > Not that this is important, but personally I never liked the name > .inject > Though fold(l/r) is not much better either. > > A peculiar thing is that the wikipedia page gives "also known variously > as " four different names as alternative/example. It's because the same thing has surfaced in several languages using different terms, and those languages have in turn influenced others. AFAIK, Matz correct me if I'm wrong, Ruby got the name inject from Smalltalk, along with collect, select, detect and several other methods. The other three I mention have alias, map for collect, find_all for select, and find for detect, but inject is still just inject in Ruby. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/ |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Hi --
On Mon, 31 Mar 2008, Rick DeNatale wrote: > On Sun, Mar 30, 2008 at 10:30 AM, Marc Heiler <shevegen@linuxmail.org> wrote: >>> Understand that it's a way to reduce/fold the elements >> > of an enumerable into a single value. >> >> Not that this is important, but personally I never liked the name >> .inject >> Though fold(l/r) is not much better either. >> >> A peculiar thing is that the wikipedia page gives "also known variously >> as " four different names as alternative/example. > > It's because the same thing has surfaced in several languages using > different terms, and those languages have in turn influenced others. > > AFAIK, Matz correct me if I'm wrong, Ruby got the name inject from > Smalltalk, along with collect, select, detect and several other > methods. The other three I mention have alias, map for collect, > find_all for select, and find for detect, but inject is still just > inject in Ruby. It picks up the synonym "reduce" in 1.9 -- which I think is kind of too bad, since inject in Ruby has such a distinctive personality and cult following :-) David -- Rails training from David A. Black and Ruby Power and Light: ADVANCING WITH RAILS April 14-17 New York City INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin See http://www.rubypal.com for details and updates! |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
On Mar 30, 2008, at 1:27 AM, 7stud -- wrote:
> By the way, using inject() is inefficient--not to mention confusing. > You might as well pretend it doesn't exist. I strongly disagree with that statement. So 7stud, you learned Python and Ruby, decided you prefer Python, and now hang out on the Ruby Talk mailing list bad mouthing our language? What's the point, if you don't mind my asking? James Edward Gray II |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
On 30.03.2008 16:32, Robert Dober wrote:
> I found this code in Ruby1.9 though > > if result.size > 0 and result.inject(false) {|k,s| s or k} > > that kind of code explains why inject has a bad reputation. That is quite a convoluted way to say result.any? Kind regards robert |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
"David A. Black" <dblack@rubypal.com> wrote in message news:Pine.LNX.4.64.0803300208460.27343@rubypal.com ... > Hi -- > > On Sun, 30 Mar 2008, Just Another Victim of the Ambient Morality wrote: > >> I'm not sure how I feel about inject's pathological case. What do you >> all think should happen in the following code? >> >> >> [2].inject {|a, i| puts i} >> >> >> I might have thought that the block would never be called and the >> method >> would return 2. >> If the block must be called, I might expect "i" to be nil. >> What actually happens is that the block is called and "i" is the same >> thing as "a". I did not expect this and I'm trying to figure out how >> this >> is either consistent or useful. Can someone clue me in to this >> behaviour? >> Thank you... > > Actually the block isn't being called: > > irb(main):005:0> [2].inject {|a, i| puts "hi" } > => 2 > irb(main):006:0> [2].inject {} > => 2 > > The value of the whole statement is 2, or, more generally, the first > (and only) element in the enumerable. I guess that's all it can do > since it doesn't have enough elements to call the block even once. D'oh! I was confused by IRB's interface, for no good reason. I'll put the crack pipe down, now. It's doing exactly what I thought it should do... |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
On Sun, Mar 30, 2008 at 8:27 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
> Oh, yeah: > > $ ruby -v > ruby 1.8.2 (2004-12-25) [universal-darwin8.0] > > > By the way, using inject() is inefficient--not to mention confusing. > You might as well pretend it doesn't exist. > I absolutely can't agree with that. map and inject are two beautiful functions which should be known for the average Ruby programmer imo. Instead of using some loops, you can easily use map to apply a function on each member. I like them. |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
They indispensible. Once you understand the other iterators, inject
becomes natural. Try doing some form of aggregation without using inject. Haha fun. # example program to illustrate inject num_ary = [10,37,27,398,273,28] # summing without inject: without_inject_sum = 0 num_ary.each{|num| without_inject_sum += num} # summing with inject with_inject_sum = num_ary.inject{|sum, num| sum + num} Julian On 31/03/2008, at 8:41 AM, Thomas Wieczorek wrote: > On Sun, Mar 30, 2008 at 8:27 AM, 7stud -- <bbxx789_05ss@yahoo.com> > wrote: >> Oh, yeah: >> >> $ ruby -v >> ruby 1.8.2 (2004-12-25) [universal-darwin8.0] >> >> >> By the way, using inject() is inefficient--not to mention confusing. >> You might as well pretend it doesn't exist. >> > > I absolutely can't agree with that. map and inject are two beautiful > functions which should be known for the average Ruby programmer imo. > Instead of using some loops, you can easily use map to apply a > function on each member. I like them. > |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
...or you could do it like this:
def collect_repeats_inject(list) return list unless list.respond_to?(:inject) collected_hash = list.inject({}) do |collected_repeats, item| ( collected_hash[item] ||= [] ) << item collected_hash end collected_hash.values end On 30/03/2008, at 8:55 PM, William James wrote: > On Mar 30, 12:27 am, 7stud -- <bbxx789_0...@yahoo.com> wrote: >> Oh, yeah: >> >> $ ruby -v >> ruby 1.8.2 (2004-12-25) [universal-darwin8.0] >> >> By the way, using inject() is inefficient--not to mention confusing. >> You might as well pretend it doesn't exist. > > There is some truth to that. > > > def collect_repeats_inject list > return [] if [] == list > list[1..-1].inject([[ list.first ]]){|a,e| > if a[-1][0] == e > a[-1] << e > else > a << [e] > end > a > }.reject{|lst| lst.size < 2 } > end > > def collect_repeats list > accum = [ [ list.shift ] ] > list.each{|e| > if accum[-1][0] == e > accum[-1] << e > else > accum << [e] > end } > accum.reject{|lst| lst.size < 2 } > end > > p collect_repeats( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) > p collect_repeats( [] ) > p collect_repeats_inject( %w(0 1 1 2 3 3 3 3 4 5 5 6) ) > p collect_repeats_inject( [] ) > > the_list = %w(0 1 1 2 3 3 3 3 3 3 3 3 4 5 5 6 7 8 8 9 9 9) > > t = Time.now > 9999.times{ collect_repeats_inject( the_list )} > p Time.now - t > t = Time.now > 9999.times{ collect_repeats( the_list )} > p Time.now - t > > --- output --- > [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] > [] > [["1", "1"], ["3", "3", "3", "3"], ["5", "5"]] > [] > 2.694 > 0.16 > > > And the version without inject is shorter and > clearer. > |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
On Sun, 30 Mar 2008 15:21:20 +0900, 7stud -- wrote:
> 2) One element array: [...] How do you print the value for "a" and "i"? thufir@arrakis:~/ruby$ thufir@arrakis:~/ruby$ ruby inject_one_element.rb result=2 thufir@arrakis:~/ruby$ thufir@arrakis:~/ruby$ cat inject_one_element.rb result = [2].inject do |a, i| puts "a:#{a}" puts "i:#{i}" puts "hello" puts "--------" end puts "result=#{result}" if result.nil? puts 'yes' end thufir@arrakis:~/ruby$ thanks, Thufir |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On Sun, 30 Mar 2008 15:27:20 +0900, 7stud -- wrote:
> By the way, using inject() is inefficient--not to mention confusing. You > might as well pretend it doesn't exist. What's the "normal" way, not using inject? -Thufir |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On Mon, 31 Mar 2008 10:06:59 +0900, Julian Leviston wrote:
> # example program to illustrate inject num_ary = [10,37,27,398,273,28] > > # summing without inject: > without_inject_sum = 0 > num_ary.each{|num| without_inject_sum += num} > > # summing with inject > with_inject_sum = num_ary.inject{|sum, num| sum + num} Thank you for the example. I'm not convinced that inject is fantastic, but certainly it's something I need to understand and this example s to illuminates it. -Thufir |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
On Sun, 30 Mar 2008 22:34:19 +0900, Rick DeNatale wrote:
> Enumerable#inject is very useful, as long as you don't treat it as > Maslow's hammer and use it in inappropriate ways, such as giving it a > block like in the original posting to this thread. Ah, the irony: when googling Maslow's hammer: Microsoft JET Database Engine error '80040e14' Syntax error (missing operator) in query expression ''http:// www.google.ca/search?q=Maslow's+hamme http://www.abraham-maslow.com/m_moti...ows_Hammer.asp ROFL, Thufir |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
On Mar 30, 11:51 am, James Gray <ja...@grayproductions.net> wrote:
> On Mar 30, 2008, at 1:27 AM, 7stud -- wrote: > > > By the way, using inject() is inefficient--not to mention confusing. > > You might as well pretend it doesn't exist. > > I strongly disagree with that statement. > > So 7stud, you learned Python and Ruby, decided you prefer Python, and > now hang out on the Ruby Talk mailing list bad mouthing our language? > What's the point, if you don't mind my asking? The same as for any troll? |
|
![]() |
| Outils de la discussion | |
|
|