823128faf73790f5ecce365c5c706cbe7f3cf186
[ruby_koans.git] / koans / about_iteration.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutIteration < EdgeCase::Koan
4   in_ruby_version("1.8") do
5     def test_each_is_a_method_on_arrays
6       assert_equal __, [].methods.include?("each")
7     end
8   end
9
10   in_ruby_version("1.9") do
11     def test_each_is_a_method_on_arrays
12       assert_equal __, [].methods.include?(:each)
13     end
14   end
15
16   def test_iterating_with_each
17     array = [1, 2, 3]
18     sum = 0
19     array.each do |item|
20       sum += item
21     end
22     assert_equal __, sum
23   end
24
25   def test_each_can_use_curly_brace_blocks_too
26     array = [1, 2, 3]
27     sum = 0
28     array.each { |item|
29       sum += item
30     }
31     assert_equal __, sum
32   end
33
34   def test_break_works_with_each_style_iterations
35     array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
36     sum = 0
37     array.each { |item|
38       break if item > 3
39       sum += item
40     }
41     assert_equal __, sum
42   end
43
44   def test_collect_transforms_elements_of_an_array
45     array = [1, 2, 3]
46     new_array = array.collect { |item| item + 10 }
47     assert_equal __, new_array
48
49     # NOTE: 'map' is another name for the 'collect' operation
50     another_array = array.map { |item| item + 10 }
51     assert_equal __, another_array
52   end
53
54   def test_select_selects_certain_items_from_an_array
55     array = [1, 2, 3, 4, 5, 6]
56
57     even_numbers = array.select { |item| (item % 2) == 0 }
58     assert_equal __, even_numbers
59
60     # NOTE: 'find_all' is another name for the 'select' operation
61     more_even_numbers = array.find_all { |item| (item % 2) == 0 }
62     assert_equal __, more_even_numbers
63   end
64
65   def test_find_locates_the_first_element_matching_a_criteria
66     array = ["Jim", "Bill", "Clarence", "Doug", "Eli"]
67
68     assert_equal __, array.find { |item| item.size > 4 }
69   end
70
71   def test_inject_will_blow_your_mind
72     result = [2, 3, 4].inject(0) { |sum, item| sum + item }
73     assert_equal __, result
74
75     result2 = [2, 3, 4].inject(1) { |product, item| product * item }
76     assert_equal __, result2
77
78     # Extra Credit:
79     # Describe in your own words what inject does.
80   end
81
82   def test_all_iteration_methods_work_on_any_collection_not_just_arrays
83     # Ranges act like a collection
84     result = (1..3).map { |item| item + 10 }
85     assert_equal __, result
86
87     # Files act like a collection of lines
88     File.open("example_file.txt") do |file|
89       upcase_lines = file.map { |line| line.strip.upcase }
90       assert_equal __, upcase_lines
91     end
92
93     # NOTE: You can create your own collections that work with each,
94     # map, select, etc.
95   end
96
97   # Bonus Question:  In the previous koan, we saw the construct:
98   #
99   #   File.open(filename) do |file|
100   #     # code to read 'file'
101   #   end
102   #
103   # Why did we do it that way instead of the following?
104   #
105   #   file = File.open(filename)
106   #   # code to read 'file'
107   #
108   # When you get to the "AboutSandwichCode" koan, recheck your answer.
109
110 end