Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Iterators

 Iterators

Jouhan's presentation on Oct. 18! We finally got into real Ruby code this week. Jouhan first covered arrays, then a while, then for, .each do, and .each with curly braces. Talked about Enumerator. Gave us an example of yield with a method that gets fibonacci numbers. She ended with a few suggested exercises =)

womenwhocode

October 19, 2011
Tweet

More Decks by womenwhocode

Other Decks in Technology

Transcript

  1. Iterators n iterate (it-uh-rayt) v. : to do something repeatedly

    n allows traversal over a collection. Tuesday, October 18, 2011
  2. Arrays n Indexed collection of objects. n Can hold all

    sorts of objects -- Strings, Fixnums, Arrays, anything! user_handles = ["minty_vinti", "ana9000", "jasmina42", "judylovestuna"] index: 0 1 2 3 Tuesday, October 18, 2011 A collection is an Object that holds references to other Objects. An Array is one example of a Collection. Objects within an Array can be referenced by their index value. Array indexes start at 0, and increment by 1 for each Object in the collection. user_handles[0] = “minty_vinti”
  3. user_handles = ["minty_vinti", "ana9000", "jasmina42", "judylovestuna"] user_handles[2] = Tuesday, October

    18, 2011 Remember that indexes start at 0. So user_handle[2] is actually going to return the third item in the list, “jasmina42”.
  4. user_handles = ["minty_vinti", "ana9000", "jasmina42", "judylovestuna"] user_handles[2] = “jasmina42” Tuesday,

    October 18, 2011 Remember that indexes start at 0. So user_handle[2] is actually going to return the third item in the list, “jasmina42”.
  5. Arrays user_handles = ["minty_vinti", "ana9000", "jasmina42", "judylovestuna"] # prints all

    users’ Twitter URLs puts "http://twitter.com/#{user_handles[0]}" puts "http://twitter.com/#{user_handles[1]}" puts "http://twitter.com/#{user_handles[2]}" puts "http://twitter.com/#{user_handles[3]}" # output http://twitter.com/minty_vinti http://twitter.com/ana9000 http://twitter.com/jasmina42 http://twitter.com/judylovestuna Tuesday, October 18, 2011 Let’s print out the URLs of all our Twitter friends by using puts. We can get all these values by explicitly stating which position in the array we’d like to print.
  6. Problem! Twitter has >200 million users. # prints all Twitter

    user’s URLs puts "http://twitter.com/#{twitter_handles[0]}" puts "http://twitter.com/#{twitter_handles[1]}" puts "http://twitter.com/#{twitter_handles[2]}" puts "http://twitter.com/#{twitter_handles[3]}" puts "http://twitter.com/#{twitter_handles[4]}" puts "http://twitter.com/#{twitter_handles[5]}" puts "http://twitter.com/#{twitter_handles[6]}" ... puts "http://twitter.com/#{twitter_handles[200000000]}" Tuesday, October 18, 2011 Writing the same code over and over again for large amounts of information will surely cause you frustration.
  7. Loops user_handles = ["minty_vinti", "ana9000", "jasmina42", "judylovestuna"] # prints all

    users’ Twitter URLs i = 0 while i < user_handles.size puts "http://twitter.com/#{user_handles[i]}" i+=1 end Check out some other types of loops here. Tuesday, October 18, 2011 Loops help you iterate over a collection! This example uses a while loop, that continues while a condition is met. In this case, we want to continue while the index (i) is less than user_handles.size (4). We’re still printing all the Twitter URLs here, but instead of specifying the index, we can store the number in a variable (i) that increases by 1 every time the loop is repeated. Sweet!!
  8. Enumerable n a class with useful functions for traversing, searching,

    and sorting over a collection, like: n next n map n inject n to use Enumerable, implement the each method Tuesday, October 18, 2011 Maybe you haven’t heard of Enumerables before, but it’s possible that you’ve already used them and didn’t even know it. If you’ve ever used a function like .each, .next, or .inject, you’ve already had experience with them! The Enumerable class gives you access to some really useful functions for traversing, searching, and sorting over a collection. Check out the Ruby doc for a list of all the things you can do.
  9. For Loop & Blocks # for loop for handle in

    user_handles url = "http://twitter.com/#{handle}" puts url end # method using a do block user_handles.each do |handle| url = "http://twitter.com/#{handle}" puts url end # method using a block with curly braces user_handles.each { |handle| puts "http://twitter.com/#{handle}" } These all print the same thing! Tuesday, October 18, 2011 Here are three ways to iterate over our user_handles array, that all print out the exact same thing. The for loop iterates over every Object in user_handles, storing the Object in the variable ‘handle’. So now, instead of accessing an Object in the array through it’s index, we can use this variable instead. The examples on the right and bottom show a method using blocks. Blocks are basically a chunk of code that can be attached to a method call. Iterators are one great use for blocks, but they can be used for much more. Generally, blocks that take up multiple lines will use the do syntax, and one-liners will use the curly braces ({ }). If we take a look at the example on the right, user_handles has a method called .each applied to it. How can this be? The Array class does not have any methods attached to it called each. Well, under the hood, the Array class is mixed in with Enumerable, giving it access to all it’s glory. The each function iterates over each item in the array, then sends it into the parameter of the block (|handle|), which then gets passed into the URL string just like in the for loop.
  10. Beware of Scope # for loop for handle in user_handles

    url = "http://twitter.com/#{handle}" puts url end puts url => “http://twitter.com/ judylovestuna” # block using do user_handles.each do |handle| url = "http://twitter.com/#{handle}" puts url end puts url => error: undefined local variable ‘url’ Tuesday, October 18, 2011 Although the for loop and block do the exact same thing in this case, be cautious of variable names and scope. The url is still accessible from outside the for loop, and will return the last value that url was saved as. But since the url variable is created from within the block for the example on the right, it is not accessible outside of that block, and will throw and error if you try to access it.
  11. Beware of Scope url = "http://google.com" for handle in user_handles

    url = "http://twitter.com/#{handle}" puts url end puts url => “http://twitter.com/ judylovestuna” url = "http://google.com" user_handles.each do |handle| url = "http://twitter.com/#{handle}" puts url end puts url => “http://twitter.com/ judylovestuna” But these print the same thing. Tuesday, October 18, 2011 In this example, we define the url before the loop and block, making it accessible afterwards. Name your variables carefully!
  12. yield allows you to: n branch out of a method,

    n execute external code, n then return back to original method 1 way to use Enumerable: Tuesday, October 18, 2011 So how can you actually use all of Enumerable’s neat methods? One way is to create an Enumerator that implements the each method. We can do this by yielding the values of your collection. Yields are cool! They allow you to leave a method, execute some code somewhere else, then return back to where you left off in your method.
  13. A yield Example def my_yield_block puts "Start of my_yield_block..." yield

    yield puts "End of my_yield_block." end my_yield_block {puts "yielding..."} # output Start of my_yield_block... yielding... yielding... End of my_yield_block. Tuesday, October 18, 2011 Here’s an example of a simple yield. The yield block (my_yield_block) prints that it’s at the start of the block, yields twice, then prints that it’s reached the end of the block. Directly below that, we call the block with instructions on what to do when the yield is hit. So upon calling the block, it prints that it’s at the start of the block, the yield causes an exit, printing “yielding...”. The program returns back to where it left off in the method, hitting another yield. This second yield causes an exit, printing “yielding...” again. The program goes back to where it left off in the method, finally printing that it’s reached the end of the block.
  14. Fibonacci with yield # Returns numbers of Fibonacci Sequence <

    max def fib(max) a, b = 0, 1 while b < max a,b = b,a+b yield b end end puts fib(4_000_000) { |x| sum += x } Tuesday, October 18, 2011 Here’s a more practical example of using a yield. This function prints the numbers in a Fibonacci sequence that are less than the value specified in the parameters (4000000). There is only one place in the code that says yield, but it is called multiple times by being in the while loop. The value is returned to |x| and the value is added to the sum.
  15. Fib as an Enumerator # An infinite collection! fib =

    Enumerator.new { |y| a = b = 1 loop { y << a a, b = b, a + b } } puts fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] fib can now use all methods in the Enumerable class Tuesday, October 18, 2011 Here’s an example of an infinite collection! Just like how our user_handles array had 4 values, this collection literally has an infinite amount. This example shows the Fibonacci sequence being stored in an Enumerator. Although we don’t explicitly say ‘yield’ in this case, the values being fed into |y| are the yielded values. An Enumerator allows you to call Enumerable methods on it, because the y within the loop is actually a Generator, which kind of simulates the creating of an each method of an Enumerator in this case, which if you remember, is how you can access the Enumerable class. In this example, we use Enumerable’s take method to print the first 10 values of our infinite collection and print them out.
  16. Something to Try Generate the first 10 prime numbers using

    a loop. Generate the first 10 prime numbers using methods from the Enumerable class. [email protected] Tuesday, October 18, 2011 Now that you’ve seen a few ways of iterating over a collection, you should try it out on your own. Feel free to email me with any questions!