Reputation: 167
I am attempting to improve my coding by working through Code Wars problems and am doing it in a specific manner. First I try working out the code on my own. Failing that I do a few Google searches (Stack Exchange) to troubleshoot. Failing that I unlock the answer to the problem and then thoroughly examine it and articulate the code in writing so I understand the code within the answer. Well, I had to the the latter today.
I understand the lion's share of the code, but I am feeling a bit shaky around my understanding of the code in the fourth line. I have done a bunch of research around the methods used in this code on Rubydocs, but still feel in the dark. Could someone please articulate it part for part for me? I am also looking for any type of advice around my current articulation of the code.
def letter_frequency(text)
chars = text.downcase.scan(/[a-zA-Z]/).sort
chars.map { |x| [x, chars.count(x)] }.uniq
.sort_by { |y| [-y[1], y[0]] }
end
set the "chars" variable to text (the parameter), lowercased, scan and return any single charecter between the range a-z or A-Z, and then sort them lowest to high.
use .map to set a key variable and return all of the charecters inside the submitted array with the total count for the key (x), and then make all charecteds unique with the .uniq method.
Then sort with the given block using the "y" key to return all of the negative/positive numbers and their count within the submitted array.
Thanks a million!
Upvotes: 0
Views: 136
Reputation: 495
sort_by
does pretty much what it sounds like. It lets you "sort" a hash based on some criteria (that you pass to a block). Since hashes don't really have an order, it returns an array sorted by the criteria you passed in the block:
Consider the following hash (count of the characters in 'hello'):
chars = {"h"=>1, "e"=>1, "l"=>2, "o"=>1}
The key is the character and the value is the count. If we wanted a sorted array of characters based on their count, we could run sort_by
on the above hash based on the value like so:
chars.sort_by { |key, value| value }
That would return the following:
[["h", 1], ["e", 1], ["o", 1], ["l", 2]]
If we wanted the most common characters first, we'd sort on -value
:
chars.sort_by { |key, value| -value }
Which would return the following:
[["l", 2], ["h", 1], ["e", 1], ["o", 1]]
I've rewritten your method with some tweaks:
def letter_frequency(text)
count = Hash.new 0
chars = text.downcase.scan(/[a-zA-Z]/)
chars.each do |char|
count[char] += 1
end
count.sort_by { |_, value| -value }
end
First, count
is the hash that stores the counts of the characters of your text, which we then sort by the count of each character (value
). The _
in the sort_by
block is a bit of shorthand because we don't use the key of the hash for anything.
Upvotes: 1