Reputation: 507
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
Reputation: 110675
Here are a few observations about your code:
test_obj
is a string, '#{tested_obj}'
is the same as #{tested_obj}
, which is the same as tested_obj
.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.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:
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
).Enumerable#min
to find the smallest value of the unsorted items (smallest
). smallest
in unsorted_array
to sorted_array
.smallest
in unsorted_array
. 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