Forum: Ruby Real life use of each_cons?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ff937b6907db49432c980f2b6a5c7e71?d=identicon&s=25 Mischa Fierer (mischa)
on 2009-01-29 06:22
Hello,

I've been going through the enumerable/enumerator methods that I'm
unfamiliar with and came across each_cons. Apart from a post by a guy
who wasn't sure where it was even defined, I have only come across one
use of it in the wild:

(From Prawn)

  def polygon(*points)
      move_to points[0]
      (points << points[0]).each_cons(2) do |p1,p2|
        line_to(*p2)
      end
    end


Does anyone have any ideas on other cases where each_cons would be
useful? Or perhaps insight into why it's in Ruby?

Best,

M
31e038e4e9330f6c75ccfd1fca8010ee?d=identicon&s=25 Gregory Brown (Guest)
on 2009-01-29 06:55
(Received via mailing list)
On Thu, Jan 29, 2009 at 12:19 AM, Mischa Fierer <f.mischa@gmail.com>
wrote:
>      move_to points[0]
>      (points << points[0]).each_cons(2) do |p1,p2|
>        line_to(*p2)
>      end
>    end
>
>
> Does anyone have any ideas on other cases where each_cons would be
> useful? Or perhaps insight into why it's in Ruby?

I think you may have been confused by my ugly code there.  I have
replaced it with:

    def polygon(*points)
      move_to points[0]
      (points[1..-1] << points[0]).each do |point|
        line_to(*point)
      end
    end

The reason why it's not needed is because we draw the lines from point
to point.

But if we were drawing them segment by segment, it'd make sense.

>> [[1,2],[3,4],[5,6],[1,2]].each_cons(2) { |a| p a }
[[1, 2], [3, 4]]
[[3, 4], [5, 6]]
[[5, 6], [1, 2]]

I imagine I had refactored a line p1, p2 call down to just line_to(p2)
without fixing the each_cons()... sorry about that.

In general each_cons is useful when you need a sliding window of size
n across a dataset.

-greg
31e038e4e9330f6c75ccfd1fca8010ee?d=identicon&s=25 Gregory Brown (Guest)
on 2009-01-29 06:59
(Received via mailing list)
On Thu, Jan 29, 2009 at 12:53 AM, Gregory Brown
<gregory.t.brown@gmail.com> wrote:
>>  def polygon(*points)
>>      move_to points[0]
>>      (points << points[0]).each_cons(2) do |p1,p2|
>>        line_to(*p2)
>>      end
>>    end
>>
>>
>> Does anyone have any ideas on other cases where each_cons would be
>> useful? Or perhaps insight into why it's in Ruby?

Here's a more reasonable usage, for solving a simple tree-traversal
problem:
http://blog.majesticseacreature.com/archives/2008....
Ff937b6907db49432c980f2b6a5c7e71?d=identicon&s=25 Mischa Fierer (mischa)
on 2009-01-29 07:17
Gregory Brown wrote:
> On Thu, Jan 29, 2009 at 12:53 AM, Gregory Brown
> <gregory.t.brown@gmail.com> wrote:
>>>  def polygon(*points)
>>>      move_to points[0]
>>>      (points << points[0]).each_cons(2) do |p1,p2|
>>>        line_to(*p2)
>>>      end
>>>    end
>>>
>>>
>>> Does anyone have any ideas on other cases where each_cons would be
>>> useful? Or perhaps insight into why it's in Ruby?
>
> Here's a more reasonable usage, for solving a simple tree-traversal
> problem:
> http://blog.majesticseacreature.com/archives/2008....

Interesting. Thanks a bunch Gregory. Traversal had occurred to me as a
possible use, but I wasn't sure.

Also, it seems that if you refactor prawn, there will be no actual usage
of each_cons on github, apart from the ruby projects of course!

M
31e038e4e9330f6c75ccfd1fca8010ee?d=identicon&s=25 Gregory Brown (Guest)
on 2009-01-29 07:50
(Received via mailing list)
On Thu, Jan 29, 2009 at 1:15 AM, Mischa Fierer <f.mischa@gmail.com>
wrote:

> Also, it seems that if you refactor prawn, there will be no actual usage
> of each_cons on github, apart from the ruby projects of course!

Already done.

http://github.com/sandal/prawn/commit/7c68dadeae3c...
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-01-29 09:09
(Received via mailing list)
2009/1/29 Mischa Fierer <f.mischa@gmail.com>:
>      move_to points[0]
>      (points << points[0]).each_cons(2) do |p1,p2|
>        line_to(*p2)
>      end
>    end
>
>
> Does anyone have any ideas on other cases where each_cons would be
> useful? Or perhaps insight into why it's in Ruby?

You can find some uses in this mailing list's archive:

http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb?key...

Useful applications are those where you need a moving window over a
collection of data, for example when calculating moving averages
(smoothing a plot) or distances between adjacent values.

Kind regards

robert
D01de334660cd0fcd941d3bf3d9d5781?d=identicon&s=25 Frantisek Havluj (moskyt)
on 2011-06-25 12:37
each_cons just saved me an unpleasant headache. I use it together with
each_line to implement file parsing with lookahead:

  f.each_line.each_cons(2) do |line, next_line|
  ...
  end
This topic is locked and can not be replied to.