Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ------------------GENERAL
- - a loop iterates over a collection, i.e.,
- it's a programming construct that's used to step through a collection of objects
- - since an Array is a collection of objects, loops can be used to iterate over arrays.
- - while iterating over a collection of objects, a loop can be programmed to
- do things to or with each object in the collection.
- ------------------EACH
- - .each is the most common way to program loop constructs
- - the .each method is called on a collection, like an Array, e.g.,
- a = [2,4,6,8]
- a.each do |num|
- # pass a block of code to .each (do...end)
- p "We're on number: #{num}"
- end
- - inside of the loop, you are instructing the computer to print
- an interpolated string with the num argument, and the num variable
- represents an element from the a array
- - with each iteration, num is assigned to a new element, i.e.,
- 2, 4, 6, and 8 in succession (in the given example)
- ------------------EACH IN RAILS
- - .each is frequently used in Rails to iterate through "model" objects
- (instances of classes representing data) and display their attributes on a page
- - we haven't yet encountered model objects and we don't yet have a web page,
- but we can explore usage like this in the example below (which shows how
- we might loop through User objects to display their info using .each):
- class User
- attr accessor :name
- def initialize(name)
- @name = name
- end
- def email
- # this is an instance method? therefore: do not pass any arguments to it?
- "#{name.split(' ').join('')}@email.com"
- end
- end
- users = [User.new("ANDREA KAO"), User.new("HERMIONE LAFORGE"), User.new("HYACINTH LAFLEUR")]
- users.each do |user|
- p "THIS USER'S NAME IS #{user.name} AND HER EMAIL IS #{user.email}."
- end
- - this loops through the users collection and outputs a string for each one
- - because .each is a method, it returns something at the end of the loop:
- the same collection of users on which it was originally called
- - **** .each performs operations on a collection, but returns the original
- collection, rather than anything related to what is performed within the
- do...end block. In this sense, we'd say that .each is used for its "side
- effects" (i.e., the printed string) rather than its "return".
- ------------------MIXING CLASSES AND LOOPS
- - this new class takes an array of user info on initialization
- - its print_names_and_emails method loops through the users and
- prints a string for each one, e.g.,
- # User class defined above
- class UserIterator
- attr_accessor :user_array
- def initialize(user_array)
- @user_array = user_array
- end
- def print_names_and_emails
- user_array.each do |user|
- p "This user's name is #{user.name} and their email is #{user.email}
- end
- end
- end
- users = [User.new("ANGELA LANSBURY"), User.new("CLORIS LEACHMAN"), User.new("HELEN MIRREN")]
- # declare the array and its values
- UserIterator.new(users).print_names_and_emails
- # chain together 2 methods: .new & .print_names_and_emails
- # this will also return the original array of users (thanks to the .each method)
- - this UserIterator class example behaves identically to the User class example above
- - it prints a string for each member of the collection (as a "side effect")
- - then the loop inside the print_names_and_emails method returns the user_array
- on which it was called
- - because this call of .each is the last thing that happens in the method, it's also,
- by default, what the method returns
- - calling UserIterator.new(users).print_names_and_emails also returns the original
- array of users with which we initialized the class instance
- ------------------PRACTICING EACH exercise
- herbs = ["lav","rose","basil"]
- herbs.each do |herb|
- p herb.upcase
- end
- # prints "LAV"\n, "ROSE"\n, "BASIL"\n
- # returns ["lav","rose","basil] - thanks to .each
- ------------------THE EACH METHOD exercise
- - again, .each returns the original array on which it's called.
- - if we want to return the value from a method using .each,
- the trick is to store outputs of each iteration in a new array,
- then return that array.
- - we'd need a local variable within the method body to collect
- the output of each iteration
- - we then return that variable by placing it on the last line, e.g.,
- def what_number_are_we_on?(array)
- new_array = []
- # initialize new_array
- array.each do |num|
- new_array << "We're on number: #{num}"
- end
- # for each item in array, shovel the value into new_array
- new_array
- # return new_array
- end
- - note that new_array must be declared as an empty array before we
- shovel items into it, else Ruby wouldn't know to treat it as an
- instance of the Array class.
- - SPECS:
- describe ArrayModifier do
- before do
- @array = ["Roxanne", "Put on the red light", "Roxanne", "Put on the red light"]
- end
- describe '#exclaim' do
- it "adds an exclamation mark to each element" do
- exclaimed = ArrayModifier.new(@array).exclaim
- expect(exclaimed).to eq(["Roxanne!", "Put on the red light!", "Roxanne!", "Put on the red light!"])
- end
- it "doesn't modify the original array" do
- original = @array.dup
- exclaimed = ArrayModifier.new(@array).exclaim
- expect(@array).to eq(original)
- end
- end
- describe '#capsify' do
- it "uppercases each element" do
- capped = ArrayModifier.new(@array).capsify
- expect(capped).to eq(["ROXANNE", "PUT ON THE RED LIGHT", "ROXANNE", "PUT ON THE RED LIGHT"])
- end
- it "doesn't modify the original array" do
- original = @array.dup
- capped = ArrayModifier.new(@array).capsify
- expect(@array).to eq(original)
- end
- end
- end
- describe StringModifier do
- describe "#proclaim" do
- it "adds an exclamation mark after each word" do
- blitzkrieg_bop = StringModifier.new("Hey ho let's go").proclaim
- expect(blitzkrieg_bop).to eq("Hey! ho! let's! go!")
- end
- end
- end
- - SOLUTION:
- class ArrayModifier
- attr_accessor :array
- def initialize(array)
- @array = array
- end
- def exclaim
- new_array = []
- array.each do |string|
- new_array << "#{string}!"
- end
- new_array
- end
- def capsify
- new_array = []
- array.each do |string|
- new_array << string.upcase
- end
- new_array
- end
- end
- class StringModifier
- attr_accessor :string
- def initialize(string)
- @string = string
- end
- def proclaim
- ArrayModifier.new(string.split(' ')).exclaim.join(' ')
- end
- end
- ------------------EACH WITH INDEX exercise
- - SPECS:
- describe '#add_value_and_index' do
- it "returns a new array composed of the value + index of each element in the former" do
- expect( add_value_and_index([2,1,0]) ).to eq([2,2,2])
- end
- end
- - SOLUTION:
- def add_value_and_index(array)
- new_array = []
- array.each_with_index do |item,index|
- new_array << (item + index)
- end
- new_array
- end
- ------------------TITLE CASE exercise
- - SPECS:
- describe "Title" do
- describe "fix" do
- it "capitalizes the first letter of each word" do
- expect( Title.new("the great gatsby").fix ).to eq("The Great Gatsby")
- end
- it "works for words with mixed cases" do
- expect( Title.new("liTTle reD Riding hOOD").fix ).to eq("Little Red Riding Hood")
- end
- it "downcases articles" do
- expect( Title.new("The lord of the rings").fix ).to eq("The Lord of the Rings")
- expect( Title.new("The sword And The stone").fix ).to eq("The Sword and the Stone")
- expect( Title.new("the portrait of a lady").fix ).to eq("The Portrait of a Lady")
- end
- it "works for strings with all uppercase characters" do
- expect( Title.new("THE SWORD AND THE STONE").fix ).to eq("The Sword and the Stone")
- end
- end
- end
- SOLUTION:
- class Title
- attr_accessor :string
- def initialize(string)
- @string = string
- end
- def fix
- prepositions = ["and","the","of","a"]
- array = string.downcase.split(' ')
- array.each_with_index do |item,index|
- if index==0 || !prepositions.include?(item)
- item.capitalize!
- end
- end
- array.join(' ')
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement