tsiege
tsiege

Reputation: 507

Making my own sort method in Ruby

So I'm new to programming, and I'm working on Chris Pine's Learn to Program, which teaches Ruby. I'm on chapter 10 trying to make my own method for an array. I was at a total loss and tried modelling mine off his suggested answer. After fiddling around, I can't get an output. I run the program and it simply ends. I even tried using his code and it's giving me the same problem.

Here's what I have so far.

unsorted_array = ['gamma', 'delta', 'beta', 'alpha', 'zeta']
sorted_array = []

def sort some_array 
  recursive_sort(some_array, [])
end


def recursive_sort(unsorted_array, sorted_array) 
  if unsorted_array.length <= 0
    return sorted_array 
  end

  still_unsorted =[]
  smallest = unsorted_array.pop
  sorted_array = []

  unsorted_array.each do |tested_obj|
    if '#{tested_obj}' > smallest
      sorted_array.push(smallest)
    else
      still_unsorted.push(smallest)
      smallest = unsorted_array.pop
    end
  end
    recursive_sort(still_unsorted, sorted_array)
end


puts sort(recursive_sort(unsorted_array, sorted_array))

Any advice would be appreciated.

Upvotes: 0

Views: 1004

Answers (1)

Cary Swoveland
Cary Swoveland

Reputation: 110675

Here are a few observations about your code:

  • since test_obj is a string, '#{tested_obj}' is the same as #{tested_obj}, which is the same as tested_obj.
  • declaring sorted_array = [] has no effect. Being a local variable, it is not within the scope of teh method recursive_sort. That method receives an array that it calls sorted_array, so you would not want it initialized anyway.
  • you don't need to create the new array, still_unsorted; simply transfer elements from unsorted_array to sorted_array.

Below I've fixed and tightened up your code.

  def recursive_sort(unsorted_array, sorted_array = []) 
    return sorted_array unless unsorted_array.length > 0
    smallest = unsorted_array.min 
    unsorted_array.each {|e| sorted_array << e if e == smallest}
    unsorted_array.delete(smallest)
    recursive_sort(unsorted_array, sorted_array)
  end

  unsorted_array = ['gamma', 'alpha', 'delta', 'beta', 'gamma', 'alpha', 'zeta']
  p recursive_sort unsorted_array
    #  => ["alpha", "alpha", "beta", "delta", "gamma", "gamma", "zeta"]

Here's what's happening:

  • by giving the second argument of recursive_sort (sorted_value) a default value of [] (an empty array), there is no need for the method sort you had previously.
  • sorted_array is returned if sorting is finished (same as return sorted_array if unsorted_array.length == 0).
  • use Enumerable#min to find the smallest value of the unsorted items (smallest).
  • add each instance of smallest in unsorted_array to sorted_array.
  • delete all instances of smallest in unsorted_array.
  • call the same method again, to remove the next smallest unsorted item, etc.

Note

  unsorted_array.each {|e| sorted_array << e if e == smallest}

could be expressed in many different ways. Here's one:

  sorted_array += [smallest]*(unsorted_array.count {|e| e == smallest})

To see how this works, suppose smallest = 'alpha'. Then

  unsorted_array.count {|e| e == 'alpha'} # => 2

so the above expression is:

  sorted_array += ['alpha']*2

which is

  sorted_array += ['alpha', 'alpha']

which adds two "alpha"'s to sorted_array.

Upvotes: 1

Related Questions