1
votes

I'm trying to build sorting method in Ruby to sort number in array. This is an example exercise from the book. The program will look at each element in the original array, and determine the lowest value of them all.

Then it add that value to a newly created array called "sorted", and remove that number from the original array.

We now have the original array losing 1 element and the new array having 1 element. We repeat the above steps with these adjusted arrays until the original one turns empty.

However, I have got the error that I can't understand what's happening:

Blockquote./sorting_argorith.rb:9:in `each': stack level too deep (SystemStackError)

This is my code:

array = [6,4,8,3,2,4,6,7,9,0,1,8,5]

def sorta array         #method wrapper
  really_sort array, []
end

def really_sort array, sorted #main method
  a = array[0]                # set a = the first element
  array.each do |i|
    if a > i
      a = i                 #check each element, if anything small than a, 
    end                     # set a to that value
  end  

  sorted.push a         #we've got the smallest element as a, 
  array.delete a        #it is then moved from the old to the new array

  if array == []
    break
  end
  really_sort array, sorted     #keep going with my two modified arrays
end                             # till the original is empty (completely moved)

sorta array         #call the wraped method

puts
print array
print sorted
2

2 Answers

1
votes

use return sorted instead of break because you are inside method not inside loop

so use this

array = [6,4,8,3,2,4,6,7,9,0,1,8,5]

def sorta(array)         #method wrapper
  really_sort(array, [])
end

def really_sort(array, sorted) #main method
  a = array[0]                # set a = the first element
  array.each do |i|
    if a > i
      a = i                 #check each element, if anything small than a, 
    end                     # set a to that value
  end

  sorted.push(a)         #we've got the smallest element as a, 
  array.delete(a)        #it is then moved from the old to the new array

  if array == []
    return sorted
  end
  really_sort(array, sorted)     #keep going with my two modified arrays
end  

sorted = sorta(array)
p sorted
# => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

BTW: Better use array.empty? instead of array == []

0
votes

There might be a problem with the proposed solution(s) -- the Array#delete method will remove all occurrences of the object you provide as a parameter. Consider the first iteration through the loop; when you call array.delete(a) with the value of 6 it will remove two sixes from the original array (indexes 0, 6).

Here's an alternative that preserves all the original elements.

array  = [6,4,8,3,2,4,6,7,9,0,1,8,5]
sorted = []
until array.empty?
  min = array.min
  idx = array.index(min)
  sorted.push(array.delete_at(idx))
end

Array#min will return the smallest value from the array

Array#index will return the index of the first occurrence of the object

Array#delete_at will remove the object at the specified index (and return it)