sorted_containers 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,12 +2,38 @@
2
2
 
3
3
  require "set"
4
4
  require_relative "sorted_array"
5
+ require "forwardable"
5
6
 
6
7
  # A module that provides sorted container data structures.
7
8
  module SortedContainers
8
- # The SortedSet class is a sorted set implementation.
9
+ # rubocop:disable Metrics/ClassLength
10
+
11
+ # SortedSet is a set that maintains its elements in sorted order.
12
+ #
13
+ # SortedSet has most of the same methods as Set, but also has the following
14
+ # additional methods:
15
+ # - #bisect_left
16
+ # - #bisect_right
17
+ # - #delete_at
18
+ # - #last
19
+ # - #[]
20
+ #
21
+ # Addtionally, there are methods that work differently than their Set counterparts.
22
+ # Generally, methods that use Entry Order will use the sort order of the keys instead.
23
+ # For example:
24
+ #
25
+ # s = Set.new
26
+ # s.add(2)
27
+ # s.add(1)
28
+ # s.first # => 2
29
+ #
30
+ # ss = SortedSet.new
31
+ # ss.add(2)
32
+ # ss.add(1)
33
+ # ss.first # => 1
9
34
  class SortedSet
10
35
  include Enumerable
36
+ extend Forwardable
11
37
 
12
38
  # Initializes a new instance of the SortedSet class.
13
39
  #
@@ -15,12 +41,158 @@ module SortedContainers
15
41
  # @param load_factor [Integer] The load factor for the sorted set.
16
42
  def initialize(iterable = [], load_factor: SortedArray::DEFAULT_LOAD_FACTOR)
17
43
  @set = Set.new(iterable)
18
- @list = SortedContainers::SortedArray.new(@set.to_a, load_factor: load_factor)
44
+ @list = SortedContainers::SortedArray.new(@set, load_factor: load_factor)
19
45
  end
20
46
 
21
- # Adds an item to the sorted set.
47
+ # Creates a new instance of the SortedSet class.
22
48
  #
23
- # @param item [Object] The item to be added.
49
+ # @param args [Array] The initial elements of the sorted set.
50
+ # @return [SortedSet] A new instance of the SortedSet class.
51
+ def self.[](*args)
52
+ new(args)
53
+ end
54
+
55
+ # @!method []
56
+ # @see SortedArray#[]
57
+ # @!method to_a
58
+ # @see SortedArray#to_a
59
+ # @!method join
60
+ # @see SortedArray#join
61
+ # @!method first
62
+ # @see SortedArray#first
63
+ # @!method last
64
+ # @see SortedArray#last
65
+ # @!method bisect_left
66
+ # @see SortedArray#bisect_left
67
+ # @!method bisect_right
68
+ # @see SortedArray#bisect_right
69
+ def_delegators :@list,
70
+ :[],
71
+ :to_a,
72
+ :join,
73
+ :first,
74
+ :last,
75
+ :bisect_left,
76
+ :bisect_right
77
+
78
+ # @!method ===
79
+ # @see Set#===
80
+ # @!method classify
81
+ # @see Set#classify
82
+ # @!method include?
83
+ # @see Set#include?
84
+ # @!method member?
85
+ # @see Set#member?
86
+ # @!method size
87
+ # @see Set#size
88
+ # @!method length
89
+ # @see Set#length
90
+ # @!method disjoint?
91
+ # @see Set#disjoint?
92
+ # @!method divide
93
+ # @see Set#divide
94
+ # @!method empty?
95
+ # @see Set#empty?
96
+ # @!method to_set
97
+ # @see Set#to_set
98
+ def_delegators :@set,
99
+ :===,
100
+ :classify,
101
+ :include?,
102
+ :member?,
103
+ :size,
104
+ :length,
105
+ :disjoint?,
106
+ :divide,
107
+ :empty?,
108
+ :to_set
109
+
110
+ # @see Set#<=>
111
+ def <=>(other)
112
+ @set <=> other.set
113
+ end
114
+
115
+ # @see Set#==
116
+ def ==(other)
117
+ @set == other.set
118
+ end
119
+
120
+ # @see Set#intersect?
121
+ def intersect?(other)
122
+ @set.intersect?(other.set)
123
+ end
124
+
125
+ # @see Set#subset?
126
+ def subset?(other)
127
+ @set.subset?(other.set)
128
+ end
129
+ alias <= subset?
130
+
131
+ # @see Set#superset?
132
+ def superset?(other)
133
+ @set.superset?(other.set)
134
+ end
135
+ alias >= superset?
136
+
137
+ # @see Set#proper_subset?
138
+ def proper_subset?(other)
139
+ @set.proper_subset?(other.set)
140
+ end
141
+ alias < proper_subset?
142
+
143
+ # @see Set#proper_superset?
144
+ def proper_superset?(other)
145
+ @set.proper_superset?(other.set)
146
+ end
147
+ alias > proper_superset?
148
+
149
+ # @see Set#intersection
150
+ def intersection(other)
151
+ SortedSet.new(@set & other.set, load_factor: @list.load_factor)
152
+ end
153
+ alias & intersection
154
+
155
+ # @see Set#union
156
+ def union(other)
157
+ SortedSet.new(@set + other.set, load_factor: @list.load_factor)
158
+ end
159
+ alias + union
160
+ alias | union
161
+
162
+ # @see Set#difference
163
+ def difference(other)
164
+ SortedSet.new(@set - other.set, load_factor: @list.load_factor)
165
+ end
166
+ alias - difference
167
+
168
+ # @see Set#^
169
+ def ^(other)
170
+ SortedSet.new(@set ^ other.set, load_factor: @list.load_factor)
171
+ end
172
+
173
+ # Clears the sorted set. Removes all elements.
174
+ # @return [SortedSet] The sorted set.
175
+ def clear
176
+ @set.clear
177
+ @list.clear
178
+ self
179
+ end
180
+
181
+ # @see Set#collect!
182
+ def collect!
183
+ return enum_for(:collect!) unless block_given?
184
+
185
+ @list.collect! do |item|
186
+ new_item = yield(item)
187
+ @set.delete(item)
188
+ @set.add(new_item)
189
+ new_item
190
+ end
191
+ self
192
+ end
193
+ alias map! collect!
194
+
195
+ # @see Set#add
24
196
  def add(item)
25
197
  return if @set.include?(item)
26
198
 
@@ -29,42 +201,54 @@ module SortedContainers
29
201
  end
30
202
  alias << add
31
203
 
32
- # Retrieves the item at the specified index.
33
- #
34
- # @param index [Integer] The index of the item to retrieve.
35
- def [](index)
36
- @list[index]
204
+ # @see Set#add?
205
+ def add?(item)
206
+ return false if @set.include?(item)
207
+
208
+ @set.add(item)
209
+ @list.add(item)
210
+ self
37
211
  end
38
212
 
39
213
  # Returns a string representation of the sorted set.
40
214
  #
41
215
  # @return [String] A string representation of the sorted set.
42
216
  def to_s
43
- "SortedSet(#{to_a.join(", ")})"
217
+ "#<SortedSet: {#{to_a.join(", ")}}>"
44
218
  end
219
+ alias inspect to_s
45
220
 
46
- # Retrieves the first item in the sorted set.
47
- #
48
- # @return [Object] The first item.
49
- def first
50
- @list.first
51
- end
221
+ # @see Set#delete
222
+ def delete(item)
223
+ return self unless @set.include?(item)
52
224
 
53
- # Retrieves the last item in the sorted set.
54
- #
55
- # @return [Object] The last item.
56
- def last
57
- @list.last
225
+ @set.delete(item)
226
+ @list.delete(item)
227
+ self
58
228
  end
59
229
 
60
- # Removes an item from the sorted set.
61
- #
62
- # @param item [Object] The item to be removed.
63
- def delete(item)
64
- return unless @set.include?(item)
230
+ # @see Set#delete?
231
+ def delete?(item)
232
+ return unless @set.include?(item) # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
65
233
 
66
234
  @set.delete(item)
67
235
  @list.delete(item)
236
+ self
237
+ end
238
+
239
+ # @see Set#delete_if
240
+ def delete_if
241
+ return enum_for(:delete_if) unless block_given?
242
+
243
+ @list.delete_if do |item|
244
+ if yield(item)
245
+ @set.delete(item)
246
+ true
247
+ else
248
+ false
249
+ end
250
+ end
251
+ self
68
252
  end
69
253
 
70
254
  # Removes the item at the specified index.
@@ -78,61 +262,116 @@ module SortedContainers
78
262
  item
79
263
  end
80
264
 
81
- # Returns the number of items in the sorted set.
82
- #
83
- # @return [Integer] The number of items.
84
- def size
85
- @list.size
265
+ # @see Set#each
266
+ def each(&block)
267
+ return enum_for(:each) unless block_given?
268
+
269
+ @list.each(&block)
270
+ self
86
271
  end
87
272
 
88
- # Checks if an item is included in the sorted set.
89
- #
90
- # @param item [Object] The item to be checked.
91
- # @return [Boolean] `true` if the item is included, `false` otherwise.
92
- def include?(item)
93
- @set.include?(item)
273
+ # @see Set#select!
274
+ def select!
275
+ return enum_for(:select!) unless block_given?
276
+
277
+ @list.filter! do |item|
278
+ if yield(item)
279
+ @set.delete(item)
280
+ true
281
+ else
282
+ false
283
+ end
284
+ end
285
+ self
94
286
  end
287
+ alias filter! select!
95
288
 
96
- # Returns an index to insert `value` in the sorted list.
97
- #
98
- # If the `value` is already present, the insertion point will be before
99
- # (to the left of) any existing values.
100
- #
101
- # Runtime complexity: `O(log(n))` -- approximate.
102
- #
103
- # @see SortedArray#bisect_left
104
- # @param value [Object] The value to insert.
105
- # @return [Integer] The index to insert the value.
106
- def bisect_left(value)
107
- @list.bisect_left(value)
289
+ # @see Set#flatten
290
+ def flatten(level = 1)
291
+ SortedSet.new(@list.flatten(level), load_factor: @list.load_factor)
108
292
  end
109
293
 
110
- # Returns an index to insert `value` in the sorted list.
111
- #
112
- # If the `value` is already present, the insertion point will be after
113
- # (to the right of) any existing values.
114
- #
115
- # Runtime complexity: `O(log(n))` -- approximate.
116
- #
117
- # @see SortedArray#bisect_right
118
- # @param value [Object] The value to insert.
119
- # @return [Integer] The index to insert the value.
120
- def bisect_right(value)
121
- @list.bisect_right(value)
294
+ # @see Set#flatten!
295
+ def flatten!(level = 1)
296
+ @set.clear
297
+ @list.flatten!(level)
298
+ @set.merge(@list)
299
+ self
122
300
  end
123
301
 
124
- # Returns the items in the sorted set as an array.
125
- #
126
- # @return [Array] The items in the sorted set.
127
- def to_a
128
- @list.to_a
302
+ # @see Set#keep_if
303
+ def keep_if
304
+ return enum_for(:keep_if) unless block_given?
305
+
306
+ @list.keep_if do |item|
307
+ if yield(item)
308
+ @set.delete(item)
309
+ true
310
+ else
311
+ false
312
+ end
313
+ end
314
+ self
129
315
  end
130
316
 
131
- # Iterates over each item in the sorted set.
132
- #
133
- # @yield [item] Gives each item to the block.
134
- def each(&block)
135
- @list.each(&block)
317
+ # @see Set#merge
318
+ def merge(other)
319
+ @set.merge(other.set)
320
+ @list.clear
321
+ @list.update(@set)
322
+ self
323
+ end
324
+
325
+ # rubocop:disable Metrics/MethodLength
326
+
327
+ # @see Set#reject!
328
+ def reject!
329
+ return enum_for(:reject!) unless block_given?
330
+
331
+ changed = false
332
+ @list.reject! do |item|
333
+ if yield(item)
334
+ @set.delete(item)
335
+ changed = true
336
+ true
337
+ else
338
+ false
339
+ end
340
+ end
341
+ changed ? self : nil
136
342
  end
343
+
344
+ # rubocop:enable Metrics/MethodLength
345
+
346
+ # @see Set#replace
347
+ def replace(other)
348
+ @set.replace(other.set)
349
+ @list.clear
350
+ @list.update(@set)
351
+ self
352
+ end
353
+
354
+ # @see Set#reset
355
+ def reset
356
+ values = @list.to_a
357
+ @set.clear
358
+ @list.clear
359
+ @set.merge(values)
360
+ @list.update(values)
361
+ self
362
+ end
363
+
364
+ # @see Set#subtract
365
+ def subtract(other)
366
+ @set.subtract(other.set)
367
+ @list.clear
368
+ @list.update(@set)
369
+ self
370
+ end
371
+
372
+ protected
373
+
374
+ attr_reader :set, :list
137
375
  end
376
+ # rubocop:enable Metrics/ClassLength
138
377
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SortedContainers
4
- VERSION = "0.1.1"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -4,3 +4,4 @@ require_relative "sorted_containers/version"
4
4
  require_relative "sorted_containers/sorted_array"
5
5
  require_relative "sorted_containers/sorted_set"
6
6
  require_relative "sorted_containers/sorted_hash"
7
+ require_relative "sorted_containers/core_extensions"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorted_containers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrison Jensen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
11
+ date: 2024-05-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A collection of sorted containers including SortedArray, SortedDict,
14
14
  and SortedSet.
@@ -26,6 +26,7 @@ files:
26
26
  - README.md
27
27
  - Rakefile
28
28
  - lib/sorted_containers.rb
29
+ - lib/sorted_containers/core_extensions.rb
29
30
  - lib/sorted_containers/sorted_array.rb
30
31
  - lib/sorted_containers/sorted_hash.rb
31
32
  - lib/sorted_containers/sorted_set.rb
@@ -55,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
56
  - !ruby/object:Gem::Version
56
57
  version: '0'
57
58
  requirements: []
58
- rubygems_version: 3.5.9
59
+ rubygems_version: 3.5.10
59
60
  signing_key:
60
61
  specification_version: 4
61
62
  summary: A collection of sorted containers including SortedArray, SortedDict, and