-
Notifications
You must be signed in to change notification settings - Fork 1
/
about_iteration.rb
133 lines (109 loc) · 4.14 KB
/
about_iteration.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require File.expand_path(File.dirname(__FILE__) + '/neo')
class AboutIteration < Neo::Koan
# -- An Aside ------------------------------------------------------
# Ruby 1.8 stores names as strings. Ruby 1.9 stores names as
# symbols. So we use a version dependent method "as_name" to convert
# to the right format in the koans. We will use "as_name" whenever
# comparing to lists of methods.
in_ruby_version("1.8") do
def as_name(name)
name.to_s
end
end
in_ruby_version("1.9", "2.0") do
def as_name(name)
name.to_sym
end
end
# Ok, now back to the Koans.
# -------------------------------------------------------------------
def test_each_is_a_method_on_arrays
assert_equal true, [].methods.include?(as_name(:each))
end
def test_iterating_with_each
array = [1, 2, 3]
sum = 0
array.each do |item|
sum += item
end
assert_equal 6, sum
end
def test_each_can_use_curly_brace_blocks_too
array = [1, 2, 3]
sum = 0
array.each { |item| sum += item }
assert_equal 6, sum
end
def test_break_works_with_each_style_iterations
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum = 0
array.each do |item|
break if item > 3
sum += item
end
assert_equal 6, sum
end
def test_collect_transforms_elements_of_an_array
array = [1, 2, 3]
new_array = array.collect { |item| item + 10 }
assert_equal [11, 12, 13], new_array
# NOTE: 'map' is another name for the 'collect' operation
another_array = array.map { |item| item + 10 }
assert_equal [11, 12, 13], another_array
end
def test_select_selects_certain_items_from_an_array
array = [1, 2, 3, 4, 5, 6]
even_numbers = array.select { |item| (item % 2) == 0 }
assert_equal [2, 4, 6], even_numbers
# NOTE: 'find_all' is another name for the 'select' operation
more_even_numbers = array.find_all { |item| (item % 2) == 0 }
assert_equal [2, 4, 6], more_even_numbers
end
def test_find_locates_the_first_element_matching_a_criteria
array = ["Jim", "Bill", "Clarence", "Doug", "Eli"]
assert_equal "Clarence", array.find { |item| item.size > 4 }
end
def test_inject_will_blow_your_mind
result = [2, 3, 4].inject(0) { |sum, item| sum + item }
assert_equal 9, result
result2 = [2, 3, 4].inject(1) { |product, item| product * item }
assert_equal 24, result2
# Extra Credit:
# Describe in your own words what inject does.
# ANSWER:
# Inject basically executes a binary operation iteratively
# on all the elements of an array together
# to return a result
end
# The map method always returns an array but can workon other collections
# as well. A key point here to remember is that Ruby will use the value
# from the last line as a return value, so that's a handy way to remember
# that seeing item + 10 will return that as a value within the result array.
def test_all_iteration_methods_work_on_any_collection_not_just_arrays
# Ranges act like a collection
result = (1..3).map { |item| item + 10 }
assert_equal [11, 12, 13], result
# Files act like a collection of lines
File.open("example_file.txt") do |file|
upcase_lines = file.map { |line| line.strip.upcase }
assert_equal ["THIS", "IS", "A", "TEST"], upcase_lines
end
# NOTE: You can create your own collections that work with each,
# map, select, etc.
end
# Bonus Question: In the previous koan, we saw the construct:
#
# File.open(filename) do |file|
# # code to read 'file'
# end
#
# Why did we do it that way instead of the following?
#
# file = File.open(filename)
# # code to read 'file'
#
# When you get to the "AboutSandwichCode" koan, recheck your answer.
# ANSWER:
# The first method iterates through the file one line at a time. The second method opens the contents of the entire file. Also from RubyDoc:
# With no associated block, File.open is a synonym for ::new. If the optional code block is given, it will be passed the opened file as an argument and the File object will automatically be closed when the block terminates. The value of the block will be returned from File.open.
end