forked from scottwillson/racing_on_rails
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharray.rb
85 lines (79 loc) · 2.19 KB
/
array.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
class Array
require 'enumerator'
# [a, b, c, d].each_row_with_index.do |row, index|
# puts("#{row}, #{index}")
# end
# >> [ a, b ], 0
# >> [ c, d ], 1
#
# Used for races table on top of results page. May be a Rails method for this, but doesn't include index, I think.
# Then again, I don't think we use index any more, either.
def each_row_with_index
return [[], 0] if empty?
rows = []
row_count = (size + 1) / 2
for row_index in 0..(row_count - 1)
row = [self[row_index]]
second_element_index = (row_count - 1) + row_index + 1
if second_element_index < size
row << self[second_element_index]
end
rows << row
yield row, row_index
end
[ rows, row_index ]
end
# Sort by +method+ and preserve existing order. Ruby 1.8 sort_by does not preserve order.
def stable_sort_by(method, order = :asc)
if order == :asc
merge_sort { |x, y|
if x.send(method).nil?
true
elsif !x.send(method).nil? && y.send(method).nil?
false
else
x.send(method) >= y.send(method)
end
}
elsif order == :desc
merge_sort { |x, y|
if y.send(method).nil?
true
elsif !y.send(method).nil? && x.send(method).nil?
false
else
x.send(method) <= y.send(method)
end
}
else
raise ArgumentError, "order must be :asc or :desc"
end
end
# Sort is stable only if predicate includes an equal comparison. Example: x.name <= y.name
def merge_sort(&predicate)
return self.dup if size <= 1
mid = size / 2
left = self[0, mid].dup
right = self[mid, size].dup
merge(left.merge_sort(&predicate), right.merge_sort(&predicate), &predicate)
end
def merge(left, right, &predicate)
sorted = []
until left.empty? or right.empty?
if predicate
if predicate.call(right.first, left.first)
sorted << left.shift
else
sorted << right.shift
end
else
if left.first <= right.first
sorted << left.shift
else
sorted << right.shift
end
end
end
sorted.concat(left).concat(right)
end
end