[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Iterating over an area in pairs.

Greg Chagnon

5/6/2006 1:00:00 AM

Is there a simple way to iterate over an array by taking any two pairs
( for this question I need one where I iterate over any two
combinations, but if someone can show how to do it by taking pairs so
that no two pairsa are duplicated that would be cool too ).

--------------------------------------------------
Thaddeus L. Olczyk, PhD
Think twice, code once.
7 Answers

Robert Klemme

5/6/2006 6:26:00 AM

0

Thaddeus L Olczyk wrote:
> Is there a simple way to iterate over an array by taking any two pairs
> ( for this question I need one where I iterate over any two
> combinations, but if someone can show how to do it by taking pairs so
> that no two pairsa are duplicated that would be cool too ).

1.8.4 doc states that there is a method each_slice that does what you
need, but my cygwin version doesn't seem to contain it:

robert@fussel ~
$ ruby -e '[1,2].each_slice(2){|*xx| p x}'
-e:1: undefined method `each_slice' for [1, 2]:Array (NoMethodError)

robert@fussel ~
$ ruby --version
ruby 1.8.4 (2005-12-24) [i386-cygwin]

You can work around in a number of ways, just an example

irb(main):004:0> a=[1,2,10,30]
=> [1, 2, 10, 30]
irb(main):005:0> 0.step(a.length-1, 2) {|i| puts a[i],a[i+1],"--"}
1
2
--
10
30
--
=> 0

Kind regards

robert

Ross Bamford

5/6/2006 7:30:00 AM

0

On Sat, 06 May 2006 07:25:37 +0100, Robert Klemme <bob.news@gmx.net> wrote:

> Thaddeus L Olczyk wrote:
>> Is there a simple way to iterate over an array by taking any two pairs
>> ( for this question I need one where I iterate over any two
>> combinations, but if someone can show how to do it by taking pairs so
>> that no two pairsa are duplicated that would be cool too ).
>
> 1.8.4 doc states that there is a method each_slice that does what you
> need, but my cygwin version doesn't seem to contain it:
>
> robert@fussel ~
> $ ruby -e '[1,2].each_slice(2){|*xx| p x}'
> -e:1: undefined method `each_slice' for [1, 2]:Array (NoMethodError)
>

In 1.8 you need to require enumerator:

$ ruby -renumerator -e '[1,2,3,4].each_slice(2){|*x| p x}'
[[1, 2]]
[[3, 4]]

In 1.9 you're already set:

$ ruby9 -e '[1,2,3,4].each_slice(2){|*x| p x}'
[[1, 2]]
[[3, 4]]

Depending on what the OP wanted, each_cons might be useful, too:

$ ruby -renumerator -e '[1,2,3,4].each_cons(2){|*x| p x}'
[[1, 2]]
[[2, 3]]
[[3, 4]]

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Martin DeMello

5/7/2006 3:24:00 PM

0

Thaddeus L Olczyk <none@none.com> wrote:
> Is there a simple way to iterate over an array by taking any two pairs
> ( for this question I need one where I iterate over any two
> combinations, but if someone can show how to do it by taking pairs so
> that no two pairsa are duplicated that would be cool too ).

Coincidentally, I wrote this yesterday (it's called Permutation because
I wanted to leave room to expand it into a generalised
permutation/combination library, but for now all I needed was the
combine method):

class Permutation
def initialize(n)
@array = n
end

def combine(k)
combinations(@array,k) {|i|
yield i
}
end

def combinations(ary, k)
if k == 1
ary.each {|i| yield [i]}
return
end
if ary.length == k
yield ary
return
else
car, *cdr = ary
combinations(cdr, k-1) {|i| yield ([car] + i)}
combinations(cdr, k) {|i| yield i}
end
end
end

Use as:
a = Permutation.new(ary)
a.combine(2) {|i,j| }

martin

Sky Yin

5/7/2006 4:52:00 PM

0

A side question. I've noticed that:
=>[[1,2], [3,4]].each{|x,y| p x,y}
>>1
>>2
>>3
>>4

but:
=>[[1,2],[3,4]].each{|x| p x}
>>[1,2]
>>[3,4]

moreover:
=>[[1,2],[3,4]].each{|x,| p x}
>>1
>>3

I couldn't find the rule of such sub-array matching in doc. Is it a
special syntax?

Ross Bamford

5/7/2006 6:41:00 PM

0

On Sun, 07 May 2006 17:52:19 +0100, Sky Yin <Sky.Yin@gmail.com> wrote:

> A side question. I've noticed that:
> =>[[1,2], [3,4]].each{|x,y| p x,y}
>>> 1
>>> 2
>>> 3
>>> 4
>
> but:
> =>[[1,2],[3,4]].each{|x| p x}
>>> [1,2]
>>> [3,4]
>
> moreover:
> =>[[1,2],[3,4]].each{|x,| p x}
>>> 1
>>> 3
>
> I couldn't find the rule of such sub-array matching in doc. Is it a
> special syntax?
>

Block arguments are handled using regular Ruby assignment rules, so
everything from *splat to nested assignment is supported. One place I
often find this useful is (contrived example):

[[:a,1],[:b,2],[:c,3]].inject({}) { |hsh,(sym, num)| hsh.merge!({ sym =>
num }) }
# => {:b=>2, :a=>1, :c=>3}

You'll find more in the Pickaxe, 2nd ed, p90-93 (or from the first edition
at http://www.rubycentral.com/book/tut_expres... - I doubt much has
changed in this regard.)

Hope that helps,
--
Ross Bamford - rosco@roscopeco.remove.co.uk

Robert Klemme

5/8/2006 5:32:00 PM

0

Ross Bamford <rosco@roscopeco.remove.co.uk> wrote:
> Block arguments are handled using regular Ruby assignment rules, so
> everything from *splat to nested assignment is supported. One place I
> often find this useful is (contrived example):
>
> [[:a,1],[:b,2],[:c,3]].inject({}) { |hsh,(sym, num)| hsh.merge!({ sym
> => num }) }
> # => {:b=>2, :a=>1, :c=>3}

I think I now why you use merge! but I'd prefer this one - a tad more
unelegant but also a tad more efficient:

[[:a,1],[:b,2],[:c,3]].inject({}) { |h,(k, v)| h[k]=v; h}
=> {:b=>2, :c=>3, :a=>1}

Kind regards

robert

Ross Bamford

5/9/2006 9:44:00 AM

0

On Mon, 08 May 2006 18:31:36 +0100, Robert Klemme <bob.news@gmx.net> wrote:

> Ross Bamford <rosco@roscopeco.remove.co.uk> wrote:
>> Block arguments are handled using regular Ruby assignment rules, so
>> everything from *splat to nested assignment is supported. One place I
>> often find this useful is (contrived example):
>>
>> [[:a,1],[:b,2],[:c,3]].inject({}) { |hsh,(sym, num)| hsh.merge!({ sym
>> => num }) }
>> # => {:b=>2, :a=>1, :c=>3}
>
> I think I now why you use merge! but I'd prefer this one - a tad more
> unelegant but also a tad more efficient:
>
> [[:a,1],[:b,2],[:c,3]].inject({}) { |h,(k, v)| h[k]=v; h}
> => {:b=>2, :c=>3, :a=>1}
>

Yeah, I started throwing merge! in there lately, mostly for that reason
but I guess it probably is quite inefficient really, especially as the
hash grows...

Thanks,
--
Ross Bamford - rosco@roscopeco.remove.co.uk