1
\$\begingroup\$

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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jul 20, 2016 at 22:13
\$\endgroup\$
6
  • \$\begingroup\$ Since appears to be off-topic for Code Review in its current state, since the code you've posted is pseudo-code. See if you can reword it to be more on-topic \$\endgroup\$ Commented Jul 20, 2016 at 22:26
  • 1
    \$\begingroup\$ @Flambino That's not pseudo code.. it will pass any Ruby interpreter (aside from the apply method) \$\endgroup\$ Commented Jul 20, 2016 at 22:28
  • 1
    \$\begingroup\$ The 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 a do_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\$ Commented Jul 20, 2016 at 22:35
  • 1
    \$\begingroup\$ @Flambino Either way, thanks for pointing out the pseudo-code rule; wasn't aware of that! I'll try to steer clear of non-legal code in the future \$\endgroup\$ Commented Jul 20, 2016 at 22:40
  • \$\begingroup\$ Did you patch the Fixnum class to define an apply method? That may be the most questionable practice in this code. \$\endgroup\$ Commented Jul 21, 2016 at 1:32

2 Answers 2

4
\$\begingroup\$

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) }
answered Jul 20, 2016 at 22:25
\$\endgroup\$
1
  • \$\begingroup\$ Can't get much simpler than that! \$\endgroup\$ Commented Jul 20, 2016 at 22:41
1
\$\begingroup\$

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 
answered Jul 20, 2016 at 22:31
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.