z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
b | blank screen |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
g | toggle follow |
r | reload slides |
n | toggle notes |
p | run preshow |
P | toggle pause |
s | choose style |
def find_evens(arr)
i = 0
evens = []
while i < arr.length
if arr[i] % 2 == 0
evens << arr[i]
end
i += 1
end
evens
end
find_evens([1,2,3,4,5,6,7,8])
def find_evens(arr)
evens = []
arr.each do |num|
evens << num if num.even?
end
evens
end
find_evens([1,2,3,4,5,6,7,8])
def find_evens(arr)
arr.select { |num| num.even? }
end
find_evens([1,2,3,4,5,6,7,8])
Mostly Arrays and Hashes
But you can define your own.
class Team
include Enumerable
def initialize(members)
@members = members
end
def each
@members.each { |m| yield m }
end
end
team.each { |m| m.say_hi! }
team.sort_by { |m| m.name }
team.max { |m| m.age }
You now have access to every method in Enumerable!
each
(1..10).each { |i| puts i }
# will print each number to the console
# returns the original collection
%w(ant bear cat).each_with_index do |a, i|
puts a if i.even?
end
# prints ant + cat
each (enumerator)
iter = (1..10).each
iter.next
=> 1
# ...
iter.next
=> StopIteration: iteration reached an end
%w(ant bear cat).each.with_index do |a, i|
puts a if i.even?
end
# prints ant + cat
[2, 4, 6, 8].all? { |n| n.even? }
=> true
[2, 4, 6, 8].any? { |n| n.odd? }
=> false
[2, 4, 6, 9].one? { |n| n.odd? }
=> true
[2, 4, 6, 8].none? { |n| n.odd? }
=> true
[2, 4, 6, 8].include? 2
=> true
# Rails only
[2, 4, 6, 8].many? { |n| n.even? }
=> true
[2, false, 6, 8].all?
=> false
[2, false, 6, 8].any?
=> true
[2, false, nil, nil].one?
=> true
[nil, false, 0, nil].none?
=> false
[nil, false, true, 1].many?
=> true
# One weird trick...
# Pythonistas HATE this!
(1..10).map { |n| n.even? } ==
(1..10).map(&:even?)
sort
[3, 1, 2, 4].sort
=> [1, 2, 3, 4]
[3, 1, 2, 4].sort { |a, b| b <=> a }
=> [4, 3, 2, 1]
sort
people.sort do |p1, p2|
if p1.name > p2.name
p1.age <=> p2.age
elsif p1.name < p2.name
p1.ssn <=> p2.ssn
else
0
end
end
sort_by
%w(bear pig!!! man).sort_by(&:length)
=> ["man", "bear", "pig!!!"]
people.sort_by { |p| [p.name, p.age] }
# careful of nil!
find / detect
[2, 4, 5, 6].find { |n| n.odd? }
# => 5
[1, 3, 5, 7].find { |n| n.even? }
# => nil
people.find { |p| p.name == "Waldo" }
select
(1..10).select(&:even?)
=> [2, 4, 6, 8, 10]
def bounce
people.select { |p| p.age >= 21 }
end
reject
(1..10).reject(&:even?)
=> [1, 3, 5, 7, 9]
def i_call_it_singles_city
people.reject { |p| p.tease? }
end
group_by
(1..10).group_by(&:even?)
=> {
false => [1, 3, 5, 7, 9],
true => [2, 4, 6, 8, 10]
}
people.group_by { |p| p.name[0] }
=> {
"K" => [kyle, kevin],
"M" => [miles, matt]
}
partition
(1..10).partition(&:even?)
=> [
[2, 4, 6, 8, 10],
[1, 3, 5, 7, 9]
]
tallies, shorties =
people.partition { |p| p.height > 6.25 }
tallies
=> [kyle, kevin]
shorties
=> [miles, matt]
map / collect
(1..10).map { |n| n * 3 }
=> [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
# different format for select box
people.map do |p|
{
id: p.id,
value: p.name
}
end
=> [
{ id: 1, value: "Kyle" },
{ id: 2, value: "Kevin" }
]
inject / reduce
(1..10).inject(0) { |sum, n| sum + n }
=> 55
# or (1..10).inject(:+)
inject / reduce
# collect stats
users.inject({}) do |stats, user|
stats[user.email] = site.visit_count_for(user)
stats
end
# email users with a calendar event today
users.inject({}) do |events, user|
events[user.email] = Event
.joins(team: { memberships: :user })
.where('start_time between ? and ?', start_time, end_time)
.where('users.id = ?', user.id)
events
end
flat_map
springfieldians.map(&:kids)
=> [
["Bart", "Lisa", "Maggie"],
["Rod", "Tod"],
["Thrillho"]
]
springfieldians.flat_map(&:kids)
=> [
"Bart", "Lisa", "Maggie",
"Rod", "Tod", "Thrillho"
]
# or map.flatten
Enumerable methods don't mutate.
arr = (1..10).to_a
numsTimes3 = arr.map { |n| n * 3 }
arr
# There are bang! methods, but
# avoid them. (map!, flatten!, etc.)
Bonus: lazy!
(1..Float::INFINITY)
.map { |n| n * 3 }
.first(10)
# infinite loop!
(1..Float::INFINITY)
.lazy
.map { |n| n * 3 }
.first(10)
=> [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
Bonus: lambdas!
under_age = ->(n) { n < 21 }
(1..30).reject(&under_age)
# or as a method
# def under_age
# ->(n) { n < 21 }
# end
Bonus: underscore.js! (or lodash)
times3 = (n) -> n * 3
result = _.map [1, 2, 3], times3
result = _([1, 2, 3]).map times3
names = [
"Allen", "Barbara", "Christine",
"Doug", "Elizabeth", "Frederick",
"George"
]
rev_cap names
=> ["NELLA", "ARABRAB", "GUOD", "EGROEG"]
My solution:
def rev_cap(names)
names
.select { |n| n.length < 8 }
.map { |n| n.reverse.upcase }
end
animals = [
["dog", "DMX"],
["dog", "Charles Barkley"],
["cat", "Whiskers"],
["fish", "Splashy McGee"],
["fish", "Swims McKenzie"]
]
count_by_type animals
=> { "dog": 2, "cat": 1, "fish": 2 }
My solution:
def count_by_type(animals)
animals.inject(Hash.new(0)) do
|counts, (type, _)|
counts[type] += 1
counts
end
end
Another solution:
def count_by_type(animals)
Hash[*animals
.group_by { |type, _| type }
.flat_map { |type, list|
[type, list.count]
}
]
end
class Item
MAX_WEIGHT = 20
MAX_DIMENSIONS = [8, 14, 18]
DIMENSIONAL_WEIGHT_FACTOR = 194
def initialize(length, width, height, weight)
@dimensions = [length, width, height]
@weight = weight
end
def oversized?
end
def dimensional_weight
@dimensions.inject(:*) / DIMENSIONAL_WEIGHT_FACTOR
end
end
My solution:
def oversized?
shipping_weight > MAX_WEIGHT ||
@dimensions
.sort
.zip(MAX_DIMENSIONS)
.any? { |d, max| d > max }
end
def shipping_weight
[dimensional_weight, @weight].max
end