Writing My Own Sorting Method (New to Ruby)

Hi,

Super new to Ruby (learning using the Chris P. book) and trying to
work through some problems. Right now I’m working on defining a method
for sorting a list of words and have written out what I think to be the
solution to the problem in English. Now I’m translating the English
version section by section and testing my code as I go via running it
and looking for errors.

At this point, I’m having a bit of trouble figuring out the correct /
best way to compare the strings within the original array to each other
and then push the smallest one to the end of the sorted array
(sortarray) and all others to the unsorted array (unsortarray). Any
helpful comments on how to go about making my code up to this point work
correctly?

Thanks a bunch,

Emeka

#Defining method for sorting a list of words

startarray = [] #starting empty array to put strings into
unsortarray = [] #unsorted array - strings are put here after the
initial sort (all sorting takes place from /within here)
sortarray = [] #sorted array - strings are pushed here after being
determined the “smallest” one

request = gets.chomp.downcase #request for words to fill array

while request != ‘’ #check to see if anything to input into array, as
long as there is a string the program keeps requesting input
startarray.push request #put any input into the end of the starting
empty array
request = gets.chomp.downcase #requests string to fill array, makes
the string lowercase, and provides information back into conditional
end

startarray.each do |start| #for each string in start array do this
if start < start #compare each string to other and if the string is
the smallest
sortarray.push start #push the string to the end of the sorted array
else
unsortarray.push start #push all strings that are not the smallest
to the end of the unsorted array
end
end

hi Emeka,

surely there are other (and better) ways to do this, but one idea that
occurs to me is that you could insert each entry from the startarray
into the sortarray at the index that is the entry’s length. of course
if you have two strings of the same length, they’ll be inserted at the
same index, but that just pushes everything up one - the entries will
still be sorted by length. you’ll also end up with a whole bunch of
nils in the sort array, but you can remove them with #compact

something like this:

startarray = %w[tiddlywinks tacks fiddlesticks jacks pez]
sortarray = []

startarray.each{|entry| sortarray.insert(entry.length, entry)}

p sortarray.compact

=> [“pez”, “jacks”, “tacks”, “fiddlesticks”, “tiddlywinks”]

hth,

  • j

On Fri, Dec 16, 2011 at 14:00, jake kaiden [email protected] wrote:

you could insert each entry from the startarray
into the sortarray at the index that is the entry’s length.

I haven’t been reading this thread closely, so forgive me if my
assumption is wrong, but… assuming you’re trying to sort by length,
that won’t work. Imagine if you have two 4-char strings inserted.
You’ll have them at indices 4 and 5. Then you get a 5-char string, so
you insert it at 5. It will push the first 4-char string up by one.
(That’s the one at 5, having been already pushed up once by the
second.). So, the 5-char one will be sandwiched between two 4-char
ones, not sorted.

You could make it OK by checking for this, and increasing the index
until either the slot is empty or what’s already there is longer.
This would be essentially an insertion sort, with a shortcut of
starting where it would be if the lengths were unique.

-Dave

hi again -

maybe this would work:

startarray = %w[abc abcdef abcd a abcde efgh def]

sortarray = startarray.sort{|x, y| x.length <=> y.length}

p sortarray

=> [“a”, “abc”, “def”, “efgh”, “abcd”, “abcde”, “abcdef”]

  • j

Dave A. wrote in post #1037062

Imagine if you have two 4-char strings inserted.
You’ll have them at indices 4 and 5. Then you get a 5-char string, so
you insert it at 5. It will push the first 4-char string up by one.
(That’s the one at 5, having been already pushed up once by the
second.). So, the 5-char one will be sandwiched between two 4-char
ones, not sorted.

good point! open hand to forehead…

  • j