-1

Given

30.02 -88.87 10.58 -99.22 107.33

to sort without the sort method. I have spent a few hours on this without any success.

def simple_sort(list)      # I have to start with this method

 list = list.split(' ')  # I understand i need to .split to get arrays

Because they're floats I need a way to make them floats with to_f method .each(&:to_f) I saw this before but I'm not sure I understand the ":". I thought colon made objects symbols so anyone please explain (&:to_f) to me?

 sorted_list = []        #thought of creating an empty array to store the new list

This is the part that gets tricky! Where do I go from here?

I want to go through each item in the array, find the smallest number and add it to the sorted_list

def sort_list(list)
  list = list.split(' ').map(&:to_f)
  sort = []
  while sort.length < list.length
    sort << list.min
    list.delete(list.min)
  end
  sort = sort.join(' ')
  return sort
end

instead of using the <=>, what would make this code work?

Diego
  • 594
  • 2
  • 10
  • 29
  • I have read algorithms for bubble sort, insertion sort, I kinda understand the concept, but lacking the creativity for the method. – Diego Oct 09 '14 at 17:19
  • 2
    `each(&:to_f)` does nothing useful. It's equivalent to `each { |i| i.to_f }` which simply converts the values to floating point numbers, then discards the results. If you want to save the result, use `map`. – tadman Oct 09 '14 at 17:23
  • 2
    There are two completely different questions here. – Patrice Gahide Oct 09 '14 at 17:23
  • interesting, thanks @tadman – Diego Oct 09 '14 at 17:50
  • so when i run this code it gives me the first 3 items in the array as it becomes equal to the length n the list. and stops. – Diego Oct 09 '14 at 19:05

1 Answers1

3

Open IRB and try things:

>> foo = '30.02 -88.87 10.58 -99.22 107.33'
"30.02 -88.87 10.58 -99.22 107.33"
>> foo.split
[
    [0] "30.02",
    [1] "-88.87",
    [2] "10.58",
    [3] "-99.22",
    [4] "107.33"
]

So split breaks the string on whitespace, so far so good.

>> foo.split.each(&:to_f)
[
    [0] "30.02",
    [1] "-88.87",
    [2] "10.58",
    [3] "-99.22",
    [4] "107.33"
]

Hmm... the values didn't change so each might not be doing what you think it does. Trying map instead:

>> foo.split.map(&:to_f)
[
    [0] 30.02,
    [1] -88.87,
    [2] 10.58,
    [3] -99.22,
    [4] 107.33
]

Once the values are converted to floats then it becomes easy to sort them.

Note: You can use the <=> operator (AKA "spaceship") to tell you whether one is less-than, equal, or greater-than another, which makes it easy to know when you should swap them. For instance:

0 <=> 1 # => -1
1 <=> 1 # => 0
2 <=> 1 # => 1

You should read the documentation for the Comparable module, which makes it really easy to add additional functionally to a class by defining the <=>(other) method.

map allows us to modify/transform an array's elements, whereas each only iterates over them. You can use each to mess with the elements, but it's not generally what you want to do since map! makes it easier to transform things.

Regarding &:to_f. This was a hack on Ruby's symbols a while back, that was added to Rails. It turned out to be so useful that it was pulled into Ruby itself. It's called a "symbol to proc" and is discussed in "Ruby ampersand colon shortcut".

Community
  • 1
  • 1
the Tin Man
  • 158,662
  • 42
  • 215
  • 303