Search code examples
arraysrubyloopsyieldbubble-sort

Ruby, bubble_sort_by(arr), code is working but returning original array


Short question:
Why my method (which is accepting blocks) is returning original array instead of modified.

Long question:
Code like this:

def bubble_sort_by(array)
  array.each_with_index do |outer, outer_index|
    array.each_with_index do |inner, inner_index|
      if yield(outer, inner) > 0
        if outer_index < inner_index
              p "outer after if: " + outer        # for debugging, indented for clarity
              p "inner after if: " + inner        # for debugging
          outer, inner = inner, outer
              p "outer after swap: " + outer      # for debugging
              p "inner after swap: " + inner      # for debugging
        end
      end
    end
  end
end

bubble_sort_by(["hi","hello","hey"]) do |left,right|
  left.length - right.length
end

In irb I see that the values of outer and inner are swapped(sorted), but the return value is still the original array.

2.3.3 :1223 >     end
"outer after if: hello"
"inner after if: hey"
"outer after swap: hey"
"inner after swap: hello"
 => ["hi", "hello", "hey"] 
2.3.3 :1224 > 

I wrote earlier similar method bubble_sort (without block) with very similar code and the original array was replaced by swapped values there.
I don't understand why the swapped values aren't saved in method mentioned here, and instead I receive original array.


Solution

  • You need to change value of array item. This is working code:

    def bubble_sort_by(array)
      array.each_with_index do |outer, outer_index|
        array.each_with_index do |inner, inner_index|
          if yield(outer, inner) > 0
            if outer_index < inner_index
                  p "outer after if: " + outer        # for debugging, indented for clarity
                  p "inner after if: " + inner        # for debugging
              outer, inner = inner, outer
                  p "outer after swap: " + outer      # for debugging
                  p "inner after swap: " + inner      # for debugging
    
              # change value array item
              array[inner_index] = inner
              array[outer_index] = outer
            end
          end
        end
      end
    end