I'm having a bit of trouble trying to find a more Rubyist way to achieve the following. Essentially, I want to try and iterate over every element e
and apply e.method(n)
for every \$n \in \text{array}\,ドル \$n \ne e\$. In order to determine whether or not \$n = e\,ドル I'll have to use an index comparison (really just test for reference equality as opposed to functional equality).
arr = [413, 321, 654, 23, 11]
(0...arr.length).each do |outer_i|
(0...arr.length).each do |inner_i|
next if outer_i == inner_i
arr[outer_i].apply arr[inner_i]
end
end
This reeks of Java/C++ and I can tell that this is not the Ruby way, but I can't seem to find an alternative. Any ideas to improve its Ruby-ness? I was thinking of Array#product
but I'm not sure where to go from there.
2 Answers 2
Note that you are just doing a permutation of two elements from a set, and there is an abstraction in the core for that, Array#permutation(n):
arr.permutation(2).each { |x, y| x.apply(y) }
-
\$\begingroup\$ Can't get much simpler than that! \$\endgroup\$Michael– Michael2016年07月20日 22:41:03 +00:00Commented Jul 20, 2016 at 22:41
Some remarks if you don't want to use the permutation
-method.
The loop with a counter on an array is not rubyesk. In ruby an iterator like Array#each
is preferred (I added the apply-method to the code to make it runnable):
class Fixnum
def apply(i)
puts "%i -- %i " % [self,i]
end
end
arr = [413, 321, 654, 23, 11]
arr.each do |outer|
arr.each do |inner|
next if outer == inner
outer.apply inner
end
end
This works, unless the array contains an entry twice (e.g. arr = [413, 321, 654, 23, 11, 11]
).
If you need the index you can use Array#.each_with_index
:
arr.each_with_index do |outer, outer_i|
arr.each_with_index do |inner, inner_i|
next if outer_i == inner_i
outer.apply inner
end
end
You may also replace the inner loop with an array without the element of the outer loop:
arr.each_with_index do |outer, outer_i|
arr2 = arr.dup #Without dup you would change the original array
arr2.delete_at(outer_i)
arr2.each do |inner|
outer.apply inner
end
end
apply
method) \$\endgroup\$apply
call is my complaint, since the code doesn't run, nor is the function of that method made clear. Hence, the code felt incomplete to me. Pseudo-code like if you'd had ado_stuff
method. However, re-reading your question, and seeing tokland's answer, I've retracted my close-vote. I felt there wasn't enough to go on, and misunderstood a few things, but I was wrong. \$\endgroup\$Fixnum
class to define anapply
method? That may be the most questionable practice in this code. \$\endgroup\$