sorted_containers 0.1.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.1.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.1.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-10-16 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.16
59
60
  signing_key:
60
61
  specification_version: 4
61
62
  summary: A collection of sorted containers including SortedArray, SortedDict, and