Git Product home page Git Product logo

phase-3-ruby-search-enumerators's Introduction

Search Enumerables

Learning Goals

  • Understand return values for enumerators.
  • Use a truthy or falsey evaluation in a block.
  • Use #select to select matching elements from a collection based on a block.
  • Use #detect to find a matching element from a collection based on a block.
  • Use #reject to filter matching elements from a collection based on a block.

Introduction

Every method in ruby must return a value. When we iterate or enumerate over a collection with #each, the return value is always the original collection. This is an example of a static return value, no matter what we do with #each, it will always return the same object that received the call to #each.

["Red", "Yellow", "Blue"].each do |color|
  puts "There are #{color.length} letters in #{color}"
end #=> ["Red", "Yellow", "Blue"]

Often we want to search for elements in a collection based on a condition. Imagine wanting to find all even numbers in a collection of numbers using #each.

matches = []
[1,2,3,4,5].each do |i|
  matches << i if i.even? # add i to the matches array if it is even
end #=> [1,2,3,4,5]
matches #=> [2,4]

Implementing a selection routine with a low-level enumerator like #each is costly in a few ways.

  1. We have to hang on to the matches within the local array matches. Programmers use the phrase maintain state to refer to this task. Cars can be in a state like "Reverse, Drive, Neutral". Our matches array has states of "Empty, [2], [2,4]".
  2. Our block is complicated with conditional logic that can be implicit with a better enumerator.
  3. Our code lacks intention and clear semantics. If we mean, #find_all or #select, why don't we just say that?

#select

When you evoke #select on a collection, the return value will be a new array containing all the elements of the collection that cause the block passed to #select to return true. That means for each iteration, if the block evaluates to true, the element yielded to that iteration will be kept in the return value array.

[1,2,3,4,5].select do |number|
  number.even?
end #=> [2,4]

In the first iteration of the block above, number will be assigned the value 1. Because 1.even? will return false, 1 will not be in the return array for this call to #select (same for 3 and 5). In the second iteration, number will be 2. Because 2.even? will return true, 2 will be in the return array (same for 4).

You can see the clarity and expressiveness of this syntax in the short block from below.

[1,2,3,4,5].select{|i| i.odd?} #=> [1,3,5]

[1,2,3].select{|i| i.is_a?(String)} #=> []

Notice that if no element makes the block evaluate to true, an empty array is returned.

#detect or #find

NOTE: detect and find are two names for the same method. For every example below we'll use detect, but you can use them interchangeably.

Whereas #select will return all elements from the original collection that cause the block to evaluate to true, #detect will only return the first element that makes the block true.

[1,2,3].detect{|i| i.odd?} #=> 1
[1,2,3].find{|i| i.odd?} #=> 1

As you can see, even though both 1 and 3 would cause the block to evaluate to true, because 1 is first in the array, it alone is returned.

[1,2,3,4].detect{|i| i.even?} #=> 2
[1,2,3,4].detect{|i| i.is_a?(String)} #=> nil

Notice also that #detect will always return a single object where #select will always return an array.

#reject

#reject will return an array with the elements for which the block is false.

[1,2].reject{|i| i.even?} #=> [1]

Conclusion

#select, #detect, and #reject are part of a family of search and filter type enumerators whose purpose is to help you refine a collection to only matching elements. They are way easier to manage than using lower-level methods like #each and create meaningful return values based on expressions in a block.

Video Review

phase-3-ruby-search-enumerators's People

Contributors

annjohn avatar aviflombaum avatar beingy avatar deniznida avatar fsultani avatar garettarrowood avatar ihollander avatar joshuabamboo avatar lizbur10 avatar maxwellbenton avatar mfitzhenry avatar sgharms avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.