Building a Word Chopper, Ruby Edition!
Tags: ruby
Published: 2020-12-03 15:33:48

My last post on this topic ([HERE](https://dev.to/crankums/building-a-string-chopper-in-js-30n6)) 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.