summaryrefslogtreecommitdiffhomepage
path: root/samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/08_arrays.txt
blob: 9904686eb4c29ed1573ec2468ec665dc6c196ef8 (plain)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# ====================================================================================
# Arrays
# ====================================================================================

# Arrays are incredibly powerful in Ruby. Learn to use them well.

repl do
  puts "* RUBY PRIMER: ARRAYS"
end

# ====================================================================================
# Enumerable ranges and .to_a
# ====================================================================================

repl do
  puts "** INFO: Create an array with the numbers 1 to 10."
  one_to_ten = (1..10).to_a
  puts one_to_ten
end

# ====================================================================================
# Finding elements
# ====================================================================================

repl do
  puts "** INFO: Finding elements in an array using ~Array#find_all~."
  puts "Create a new array that only contains even numbers from the previous array."

  one_to_ten = (1..10).to_a
  evens = one_to_ten.find_all do |number|
    number % 2 == 0
  end

  puts evens
end

# ====================================================================================
# Rejecting elements
# ====================================================================================

repl do
  puts "** INFO: Removing elements in an array using ~Array#reject~."
  puts "Create a new array that rejects odd numbers."

  one_to_ten = (1..10).to_a
  also_even = one_to_ten.reject do |number|
    number % 2 != 0
  end

  puts also_even
end

# ====================================================================================
# Array transform using the map function.
# ====================================================================================

repl do
  puts "** INFO: Creating new derived values from an array using ~Array#map~."
  puts "Create an array that doubles every number."

  one_to_ten = (1..10).to_a
  doubled = one_to_ten.map do |number|
    number * 2
  end

  puts doubled
end

# ====================================================================================
# Combining array functions.
# ====================================================================================

repl do
  puts "** INFO: Combining ~Array#find_all~ along with ~Array#map~."
  puts "Create an array that selects only odd numbers and then multiply those by 10."

  one_to_ten = (1..10).to_a
  odd_doubled = one_to_ten.find_all do |number|
    number % 2 != 0
  end.map do |odd_number|
    odd_number * 10
  end

  puts odd_doubled
end

# ====================================================================================
# Product function.
# ====================================================================================

repl do
  puts "** INFO: Create all combinations of array values using ~Array#product~."
  puts "All two-item pairs of numbers 1 to 10."
  one_to_ten = (1..10).to_a
  all_combinations = one_to_ten.product(one_to_ten)
  puts all_combinations
end

# ====================================================================================
# Uniq and sort function.
# ====================================================================================

repl do
  puts "** INFO: Providing uniq values using ~Array#uniq~ and ~Array#sort~."
  puts "All uniq combinations of numbers regardless of order."
  puts "For example: [1, 2] is the same as [2, 1]."
  one_to_ten = (1..10).to_a
  uniq_combinations =
    one_to_ten.product(one_to_ten)
              .map do |unsorted_number|
                unsorted_number.sort
              end.uniq
  puts uniq_combinations
end

# ====================================================================================
# Example of an advanced array transform.
# ====================================================================================

repl do
  puts "** INFO: Advanced chaining. Combining ~Array's ~map~, ~find_all~, ~sort~, and ~sort_by~."
  puts "All unique Pythagorean Triples between 1 and 100 sorted by area of the triangle."

  one_to_hundred = (1..100).to_a

  triples =
    one_to_hundred.product(one_to_hundred).map do |width, height|
                [width, height, Math.sqrt(width ** 2 + height ** 2)]
              end.find_all do |_, _, hypotenuse|
                hypotenuse.to_i == hypotenuse
              end.map do |triangle|
                triangle.map(&:to_i)
              end.uniq do |triangle|
                triangle.sort
              end.map do |width, height, hypotenuse|
                [width, height, hypotenuse, (width * height) / 2]
              end.sort_by do |_, _, _, area|
                area
              end

  triples.each do |width, height, hypotenuse, _|
    puts "(#{width}, #{height}, #{hypotenuse})"
  end
end

# ====================================================================================
# Example of an sorting.
# ====================================================================================

repl do
  puts "** INFO: Implementing a custom sort function that operates on the ~Hash~ datatype."

  things_to_sort = [
    { type: :background, order: 1 },
    { type: :foreground, order: 1 },
    { type: :foreground, order: 2 }
  ]
  puts "*** Original array."
  puts things_to_sort

  puts "*** Simple sort using key."
  # For a simple sort, you can use sort_by
  results = things_to_sort.sort_by do |hash|
    hash[:order]
  end

  puts results

  puts "*** Custom sort."
  puts "**** Sorting process."
  # for a more complicated sort, you can provide a block that returns
  # -1, 0, 1 for a left and right operand
  results = things_to_sort.sort do |l, r|
    sort_result = 0
    puts "here is l: #{l}"
    puts "here is r: #{r || "nil"}"
    # if either value is nil/false return 0
    if !l || !r
      sort_result = 0
    # if the type of "left" is background and the
    # type of "right" is foreground, then return
    # -1 (which means "left" is less than "right"
    elsif l[:type] == :background && r[:type] == :foreground
      sort_result = -1
    # if the type of "left" is foreground and the
    # type of "right" is background, then return
    #  1 (which means "left" is greater than "right"
    elsif l[:type] == :foreground && r[:type] == :background
      sort_result = 1
    # if "left" and "right"'s type are the same, then
    # use the order as the tie breaker
    elsif l[:order] < r[:order]
      sort_result = -1
    elsif l[:order] > r[:order]
      sort_result = 1
    # returning 0 means both values are equal
    else
      sort_result = 0
    end
    sort_result
  end.to_a

  puts "**** Sort result."
  puts results
end

# ====================================================================================
# Api documention for Array that is worth commiting to memory because arrays are so
# awesome in Ruby: https://docs.ruby-lang.org/en/2.0.0/Array.html
# ====================================================================================