Skip to content

Instantly share code, notes, and snippets.

@randalmaile
Last active December 30, 2015 18:19
Show Gist options
  • Save randalmaile/7866409 to your computer and use it in GitHub Desktop.
Save randalmaile/7866409 to your computer and use it in GitHub Desktop.
Loops checkpoint
## Each loop
1. With the each loop, the |item| arguement represents the element of a "collection", and in the examples provided, it's an array.
2. The each method is passed a block, which == the instructions or operations you're performing on the elements of the collection
## While loop
1. The while loop iterates over a collection based on a condition. Unlike the each method, which iterates over a collection based on the number of elements in that collection, while evaluates a condition with each iteration, and then either executes the loop, or ends the loop
2. Seems straightforward - typical while loop.
``` Block output - The Each method
```
Array sum_numbers sums random numbers
String camel_case leaves first word lowercase
String camel_case should lowercase first letter if it isn't
String camel_case should combine words using camel case
String camel_case should downcase words with capitals
Array add_index adds index to numbers
Array add_index adds index to strings
``` Block output - Title Case
```
String Title case capitalizes the first letter of each word
String Title case works for words with mixed cases
String Title case ignores articles
String Title case works for strings with all uppercase characters
I actually had a hard time w/ this one - took me a couple of hours. Was never too good at loops....
Here's where I got stuck:
THE EACH METHOD
- String class: camel_case method:
- I didn't know how to change the array in place. So I googled around and remembered in JS, that you have to create a new array and populate that new array with the modified elements. Is there another way to do this with the array "in place?" Not sure if that makes sense. Just thought creating a new array was not so elegant.
TITLE CASE
- String class: title_case
- Again, I created a new array - I guess this is correct?
- I couldn't think of how to use the include? method? Ideas?
- My code doesn't "feel" efficient? Any comments?
# Each loop (non-assignment practice)
[1] pry(main)> a = ["red", "blue", "green"]
=> ["red", "blue", "green"]
[2] pry(main)> a.each do |color|
[2] pry(main)* p "The color is #{color}"
[2] pry(main)* end
"The color is red"
"The color is blue"
"The color is green"
=> ["red", "blue", "green"]
# While loop (non-assignment practice)
[1] pry(main)> numbers = [22,333,4444,55555,666666,7777777]
=> [22, 333, 4444, 55555, 666666, 7777777]
[2] pry(main)> index = 0
=> 0
[3] pry(main)> while numbers[index]
[3] pry(main)* p numbers[index]
[3] pry(main)* index += 1
[3] pry(main)* end
22
333
4444
55555
666666
7777777
=> nil
#THE EACH METHOD
class Array
def sum_numbers
sum=0
self.each do |num|
sum+=num
end
sum
end
def add_index
addIndexToElements = []
self.each_with_index do |item, index|
addIndexToElements << "#{index} is #{item}"
end
addIndexToElements
end
end
class String
def camel_case
camCaseArray = []
self.split.each_with_index do |item, index|
if index == 0
camCaseArray << item.downcase
else
camCaseArray << item.capitalize
end
end
camCaseArray.join
end
end
# TITLE CASE
class String
def title_case
newAr = []
self.split.each_with_index do |item, index|
dc = item.downcase
if ((dc == "and" || dc == "a" || dc == "the" || dc == "of") && index != 0)
newAr << dc
else
newAr << item.capitalize
end
end
newAr.join(" ")
end
end
@mkwiatkowski
Copy link

Re: camel_case

Changing array in place vs. making a new one is not a matter of elegance, rather a programming style. When you make a new array based on some other array it's in functional programming style. When you modify it in place it is in imperative programming style. Personally I find functional style much more testable and reusable, while imperative code tends to be harder to reuse later, even if it has better performance (both computationally and in terms of memory use).

If you wanted to use imperative style here, it would look like this:

class String
  def camel_case
    a = self.split
    a.each_with_index do |item, index|
      if index == 0
        item.downcase!
      else
        item.capitalize!
      end
    end
    a.join
  end
end

Notice the use of bang methods.

So the idea is that you don't modify the array itself (elements stay where they were), but you just modify the elements themselves (i.e. downcase or capitalize the strings).

@mkwiatkowski
Copy link

Re: title_case

I've showed you how to use include there during the meeting, so I'll just paste that here, so that you have the notes:

class String
  def title_case
    articles = ["and", "a", "the", "of"]
    newAr = []
    self.split.each_with_index do |item, index|  
      dc = item.downcase          
      if (articles.include?(item) && index != 0)
        newAr << dc
      else
        newAr << item.capitalize
      end
    end  
    newAr.join(" ")
  end   
end

You could also do some clean up on this code. I've already replaced 4-space indentation with 2-space - that's the standard for Ruby code.

Another thing you could do is get rid of the parens around condition in fi:

if articles.include?(item) && index != 0

Also, instead of downcasing each word during iteration you could downcase the whole string before splitting:

    self.downcase.split.each_with_index do |item, index|  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment