periodical 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/periodical/filter.rb +32 -23
- data/lib/periodical/version.rb +1 -1
- data/spec/periodical/filter_spec.rb +3 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2555e6758e16ddd84d99a9f56a223cd8c19cdfe1
|
4
|
+
data.tar.gz: 3187ffebf9e51e9175a76d2321ea1b2c2b516b3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7adb54adb0d5d51a4193e8519497f57412beeb043ca4c145f850894e59cb684e25e149ec29c414fc51991f40ebcd5a2c0451da5d25809492ef81a549757054c8
|
7
|
+
data.tar.gz: 92a27112f8b1c656b5e7f368dfd6f776c3ee017243656c75785a94640c64df4febe673cd8e8c8c634ca449b6d204daafae9cf4ac4209b8a22752c4274dde02cc
|
data/lib/periodical/filter.rb
CHANGED
@@ -26,35 +26,44 @@ module Periodical
|
|
26
26
|
module Filter
|
27
27
|
# Keep count sorted objects per period.
|
28
28
|
class Period
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
# Given times a and b, should we prefer a?
|
30
|
+
ORDER = {
|
31
|
+
# We want `a` if `a` < `b`, i.e. it's older.
|
32
|
+
old: ->(a, b){a < b},
|
33
|
+
|
34
|
+
# We want `a` if `a` > `b`, i.e. it's newer.
|
35
|
+
new: ->(a, b){a > b}
|
36
|
+
}
|
37
|
+
|
38
|
+
# @param count the number of items we should retain.
|
37
39
|
def initialize(count)
|
38
40
|
@count = count
|
39
41
|
end
|
40
42
|
|
41
|
-
|
43
|
+
# @param order can be a key in ORDER or a lambda.
|
44
|
+
# @param block is applied to the value and should typically return a Time instance.
|
45
|
+
def filter(values, keep: :old, &block)
|
42
46
|
slots = {}
|
43
|
-
|
44
|
-
keep = (
|
45
|
-
|
47
|
+
|
48
|
+
keep = ORDER.fetch(keep, keep)
|
49
|
+
|
46
50
|
values.each do |value|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
slots[
|
51
|
+
time = block_given? ? yield(value) : value
|
52
|
+
|
53
|
+
granular_key = key(time)
|
54
|
+
|
55
|
+
# We filter out this value if the slot is already full and we prefer the existing value.
|
56
|
+
if existing_value = slots[granular_key]
|
57
|
+
existing_time = block_given? ? yield(existing_value) : existing_value
|
58
|
+
next if keep.call(existing_time, time)
|
59
|
+
end
|
60
|
+
|
61
|
+
slots[granular_key] = value
|
53
62
|
end
|
54
|
-
|
63
|
+
|
55
64
|
sorted_values = slots.values.sort
|
56
|
-
|
57
|
-
return sorted_values
|
65
|
+
|
66
|
+
return sorted_values.first(@count)
|
58
67
|
end
|
59
68
|
|
60
69
|
def key(t)
|
@@ -113,11 +122,11 @@ module Periodical
|
|
113
122
|
@periods[period.class] = period
|
114
123
|
end
|
115
124
|
|
116
|
-
def filter(values, options
|
125
|
+
def filter(values, **options, &block)
|
117
126
|
filtered_values = Set.new
|
118
127
|
|
119
128
|
@periods.values.each do |period|
|
120
|
-
filtered_values += period.filter(values, options)
|
129
|
+
filtered_values += period.filter(values, **options, &block)
|
121
130
|
end
|
122
131
|
|
123
132
|
return filtered_values, (Set.new(values) - filtered_values)
|
data/lib/periodical/version.rb
CHANGED
@@ -36,11 +36,9 @@ module Periodical::PeriodSpec
|
|
36
36
|
policy << Periodical::Filter::Daily.new(3)
|
37
37
|
|
38
38
|
selected, rejected = policy.filter(dates)
|
39
|
-
expect(selected.count).to be 3
|
40
|
-
expect(rejected.count).to be 3
|
41
39
|
|
42
|
-
|
43
|
-
expect(
|
40
|
+
expect(selected).to include(*dates.first(3))
|
41
|
+
expect(rejected).to include(*dates.last(3))
|
44
42
|
end
|
45
43
|
|
46
44
|
it "should keep youngest" do
|
@@ -52,7 +50,7 @@ module Periodical::PeriodSpec
|
|
52
50
|
policy = Periodical::Filter::Policy.new
|
53
51
|
policy << Periodical::Filter::Monthly.new(1)
|
54
52
|
|
55
|
-
selected, rejected = policy.filter(dates, :keep => :
|
53
|
+
selected, rejected = policy.filter(dates, :keep => :new)
|
56
54
|
expect(selected.count).to be 1
|
57
55
|
expect(rejected.count).to be 1
|
58
56
|
|