I seem to end up doing the following quite a lot:
enum.each do |a|
enum.each do |b|
next if a >= b
# do_something with a and b
end
end
In general, I’m looking for an idiomatic way of traversing each
possible pair of a given enum’s contents (once). Is there a more
compact construct?
(I assume I could finally grasp the whole block-passing side of Ruby
and write my own Enumerable#each_mix, but maybe there’s something there
already. Note: Enumerable#each_pair doesn’t cut it, as it’s just for
neighbouring element pairs, while I need something for all possible
pairs.)
Thanks in advance for any help with the above!
– Shot
On Dec 15, 2007, at 6:03 PM, Shot (Piotr S.) wrote:
possible pair of a given enum’s contents (once). Is there a more
– Shot
The existential root of libertarianism is the experience of
being very bad at taking orders from morons. – Leopold Leider
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/42671
You could use the Array#combination code posted there either directly
or as an example. If you can rely on the ordering of elements (your
a>=b), your code isn’t too bad, but the code on the ruby list will be
(is) part of Ruby1.9 and only depends on position within the Array.
If you have an enumerable that’s not an Array, you might have some
tweaking to do anyway.
-Rob
Rob B. http://agileconsultingllc.com
[email protected]
On Dec 15, 6:25 pm, Rob B. [email protected]
wrote:
end
neighbouring element pairs, while I need something for all possible
[email protected]
module Enumerable
def every_pair(other)
self.each { | x |
other.each { | y |
yield [x, y] if x < y
}
}
end
end
a = [1, 8, 3]
b = [4, 5, 6]
a.every_pair(b) { | x, y |
puts "doing stuff with " + [x, y].inspect
}
=>
doing stuff with [1, 4]
doing stuff with [1, 5]
doing stuff with [1, 6]
doing stuff with [3, 4]
doing stuff with [3, 5]
doing stuff with [3, 6]
Regards,
Jordan
MonkeeSage:
module Enumerable
def every_pair(other)
self.each { | x |
other.each { | y |
yield [x, y] if x < y
}
}
end
end
Ah, perfect. In my (limited) case, it ended up to be
module Enumerable
def every_pair
each_with_index do |a, i|
each_with_index do |b, j|
yield [a, b] if i < j
end
end
end
end
arr = (1…5).sort_by { rand }
=> [1, 4, 2, 5, 3]
arr.every_pair { |a, b| p [a, b] }
[1, 4]
[1, 2]
[1, 5]
[1, 3]
[4, 2]
[4, 5]
[4, 3]
[2, 5]
[2, 3]
[5, 3]
=> [1, 4, 2, 5, 3]
Most appreciated!
– Shot
On Dec 15, 6:03 pm, “Shot (Piotr S.)” [email protected] wrote:
possible pair of a given enum’s contents (once). Is there a more
compact construct?
Facets exits for you.
http://facets.rubyforge.org/rdoc/core/classes/Enumerable.html#M000450
T.
http://facets.rubyforge.org
Trans:
On Dec 15, 6:03 pm, “Shot (Piotr S.)” [email protected] wrote:
In general, I’m looking for an idiomatic way of traversing
each possible pair of a given enum’s contents (once).
Facets exits for you.
(I can’t help but love the typo.)
http://facets.rubyforge.org/rdoc/core/classes/Enumerable.html#M000450
Ah, thanks – I have both Facets’ and Utility Belt’s documentation
on my to-read list, but didn’t have the time yet. 
– Shot
Rob B.:
On Dec 15, 2007, at 6:03 PM, Shot (Piotr S.) wrote:
In general, I’m looking for an idiomatic way of traversing
each possible pair of a given enum’s contents (once).
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/42671
You could use the Array#combination code
posted there either directly or as an example.
Thanks a lot!
In a related field, the above touched some obscure part of my brain
and I recalled the permutation gem: http://permutation.rubyforge.org/
If you can rely on the ordering of elements
(your a>=b), your code isn’t too bad
If I can’t rely on it, I use each_with_index:
each_with_index do |a, i|
each_with_index do |b, j|
next if i >= j
# do something with a and b
end
end
If you have an enumerable that’s not an Array,
you might have some tweaking to do anyway.
The above each_with_index works quite well for most
(all?) enumerables.
Thanks again for your reply!
– Shot