4
\$\begingroup\$

This exercise involves taking an array of numbers and sorting them alphabetically. For example, [1,2,3,4] would return as [4,1,3,2]

I mapped the array first, returning an array of words, then sorted those words using Ruby's built-in sort function. Then, I mapped that array to return an array of integers.

It works, obviously. I want your suggestions and thoughts, different ideas and better ways I could do this in the future.

I know I could one-line the map functions, but thought this is better for readability. Example: alphabeticize = numbers.map {|num| alphas.fetch(:"#{num.to_s}")}.sort

def alphabetic_number_sort(numbers)
 alphas = {"0": "zero", "1": "one", "2": "two", "3": "three", "4": "four", "5": "five", "6": "six", "7": "seven", "8": "eight", "9": "nine", "10": "ten", "11": "eleven", "12": "twelve", "13": "thirteen", "14": "fourteen", "15": "fifteen", "16": "sixteen", "17": "seventeen", "18": "eighteen", "19": "nineteen"}
 alphabeticize = numbers.map do |num|
 alphas.fetch(:"#{num.to_s}")
 end.sort
 sorted_alphabetically = alphabeticize.map do |word|
 alphas.key(word).to_s.to_i
 end
 return sorted_alphabetically
end
p alphabetic_number_sort((0..19).to_a) == [
 8, 18, 11, 15, 5, 4, 14, 9, 19, 1, 7, 17,
 6, 16, 10, 13, 3, 12, 2, 0
]
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Sep 16, 2017 at 3:58
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

sort_by cleans this up quite a bit, and avoids the unnecessary conversions to and from strings:

def sort_alphabetically(numbers)
 alphas = %w(zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen)
 .map.with_index {|x,i| [i, x]}.to_h
 numbers.sort_by {|x| alphas[x]}
end

Notes:

  1. Point on naming: use a verb, or else a noun describing what the function returns: sort_alphabetically or alphabetically_sorted. I know technically alphabetically_sorted isn't a noun, but I see it as an abbreviation for alphabetically_sorted_list, which is too verbose.

  2. If speed matters, you should compute the hash outside the function, so it's only done once.

answered Sep 17, 2017 at 2:57
\$\endgroup\$
1
  • \$\begingroup\$ Nice, thank you. I will study this further. Also, I think I accidentally "down voted" you answer :/ \$\endgroup\$ Commented Sep 18, 2017 at 9:24
2
\$\begingroup\$

When defining the alphas hash, I would consider strings to be more appropriate as keys than symbols. That would help eliminate the awkward colon during lookup in alphas.fetch(:"#{num.to_s}").

However, I question the need for a hash at all. Why not write it as an array?

ENGLISH_NUMS = %w(
 zero one two three four five six seven eight nine
 ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen
)

Then, it's a simple matter of using Enumerable#sort_by.

def alphabetic_number_sort(numbers)
 numbers.sort_by { |n| ENGLISH_NUMS[n] }
end

Note that it is common practice to omit the explicit return in Ruby.

answered Sep 17, 2017 at 6:50
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.