My last post on this topic (HERE) made a word chopper in JavaScript. Today’s post will be on the same thing, but in Ruby! And boy, I was glad to do it, as it turns out that I forgot a lot of Ruby.
One of my issues in Ruby, besides having spent a lot of time in JS and various frameworks recently, is that because I learned it as my “intro to coding” language, I have a tendency to write my code out the long way, so sometimes I’ll write a block, when really, there’s just a method call or idiom that does what I need.
Before we dive into the code, let’s go back over the premise real quick. I’d like to write some code that returns 3-5 slices of a search that I’ll use to check my database for entries related to a certain product or category. Since some rows have an abbreviated or misspelled name, searching for parts of them rather than the whole thing is the way to go. For example, if I want to search for Hershey’s chocolate bars, I should search for “HERSH”, “HRSY”, and “HRSH”, as well as “CHOC”, “CHCL”, etc.
My challenge here was finding a way to iterate the string to make slices of it. There are a lot of ways to iterate a string in Ruby, such as the #split
or #each_char
methods. But the truth is, we’re not inspecting each character of the string for something, we’re moving our starting index down the length of the string and making a slice from there of our desired length.
Let’s try a while do
loop, for … reasons. Honestly, it was the easier one to write for me.
def chopper3(str)
i=0 #declare a starting index variable
retArr=[] #make a container to put the substrings in
while i<str.length do
retArr.push(str.slice(i,3))
i+=1
end
retArr #return the array
end
Not bad, let’s see the output:
>input = ‘hersheys’
>puts chopper3(input)
her
ers
rsh
she
hey
eys
ys
s
Eh, alright, but we see some issues as we get to the end of the string. Let’s toss a little conditional in there
def chopper3(str)
i=0
retArr=[]
while i<str.length do
retArr.push(str.slice(i,3)) unless str.slice(i,3).length < 3
i+=1
end
retArr
end
Now, it’ll just include slices that are three characters long. Same as last time, though, our problem is that I’ll have to write a new method every time I want a different length of slice. How can I address this? Let’s add an additional argument:
def chopper(str, len)
i=0
retArr = []
while i<str.length do
retArr.push(str.slice(i, len)) unless str.slice(i, len).length < len
i+=1
end
retArr
end
Alright, let’s look at some outputs:
>query_object[:three_letters]= chopper(input, 3)
>query_object[:four_letters]= chopper(input, 4)
>query_object[:five_letters]= chopper(input, 5)
Output:
{:three_letters=>["her", "ers", "rsh", "she", "hey", "eys"],
:four_letters=>["hers", "ersh", "rshe", "shey", "heys"],
:five_letters=>["hersh", "ershe", "rshey", "sheys"]}
Alright, not bad. Now let’s try a vowel remover. Same as with JS, I could split the string, look for vowels, remove them, then rejoin the string. If there’s a reason I should do it that way, please let me know. Until then, good ol’ regexp, specifically the #gsub
method this time:
def remove_vowels(str)
str.gsub(/[aeiou]/i,'')
end
To tell the truth, I may not have actually had to write a method to remove the vowels, as doing so is a one-liner as it is. Ah, well, let’s integrate it into our #chopper
method:
def chopper(str, len, vowels=false)
if vowels
str = remove_vowels(str)
end
i=0
retArr = []
while i<str.length do
retArr.push(str.slice(i, len)) unless str.slice(i, len).length < len
i+=1
end
retArr
end
Something I do miss about Ruby is not constantly parenthesizing and curly-bracketing everything. But let’s take out a couple lines here:
def chopper(str, len, vowels=false)
vowels ? str = remove_vowels(str) : str
i=0
retArr = []
while i<str.length do
retArr.push(str.slice(i, len)) unless str.slice(i, len).length < len
i+=1
end
retArr
end
A little cleaner than before.
So, same place as my last post on building a slicer. We’ve built a flexible method, and we can make slices by length and with or without vowels. It’s still being displayed as a hash with array values consisting of substrings. So our questions are:
-How should we handle output on this code?
-What other filters/options should we look at?
-How should we deploy this code?
For fun, I’m eventually going to deploy this in both its JS and Ruby versions, consisting of a simple input and checkboxes and maybe give it to the company I work for as a training tool (and then I can call it code in production that I’m maintaining!)
As always, any bits on refactoring or less efficient but funnier ways of doing the jobs, I’m all ears.
Top comments (0)