xqsr3 0.31.2 → 0.32.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +2 -1
- data/README.md +32 -3
- data/examples/count_word_frequencies.md +82 -0
- data/examples/count_word_frequencies.rb +49 -0
- data/lib/xqsr3/array_utilities/join_with_or.rb +3 -3
- data/lib/xqsr3/containers/frequency_map.rb +182 -59
- data/lib/xqsr3/containers/multi_map.rb +4 -2
- data/lib/xqsr3/conversion/bool_parser.rb +4 -4
- data/lib/xqsr3/conversion/integer_parser.rb +4 -4
- data/lib/xqsr3/extensions/enumerable/unique.rb +13 -23
- data/lib/xqsr3/extensions/kernel/integer.rb +4 -4
- data/lib/xqsr3/extensions/test/unit/assert_not.rb +2 -2
- data/lib/xqsr3/extensions/test/unit/assert_type_has_instance_methods.rb +1 -1
- data/lib/xqsr3/io/writelines.rb +4 -4
- data/lib/xqsr3/string_utilities/ends_with.rb +3 -3
- data/lib/xqsr3/string_utilities/nil_if_empty.rb +3 -3
- data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +3 -3
- data/lib/xqsr3/string_utilities/quote_if.rb +4 -4
- data/lib/xqsr3/version.rb +2 -2
- data/test/unit/containers/tc_frequency_map.rb +58 -5
- data/test/unit/extensions/enumerable/tc_unique.rb +24 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d08b7ea53bfd21226d79bb36506890a7868ba93b
|
4
|
+
data.tar.gz: c4d23e493010555d8c3cfb27c515b469a47dd29f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34a1d293c2de8559801ec22e038a4e7fc33a7d6da5901411d84f1aa6ca67cd22295f690ecc501b166e9aa8777f5b00408473b467782ff129ebade29e0a0e15e0
|
7
|
+
data.tar.gz: 9e9a153905629a84437e69ea297ca7bbc843542a3ab90b35997d1e79d816ded0d90d2c2e8381c9db13ca6ffe6a4a8ae0691c2db5a7b4478a58efef4dc2e52ee4
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
xqsr3
|
2
2
|
|
3
|
-
Copyright (c) 2005-
|
3
|
+
Copyright (c) 2005-2019, Matthew Wilson and Synesis Software
|
4
4
|
All rights reserved.
|
5
5
|
|
6
6
|
Redistribution and use in source and binary forms, with or without
|
@@ -27,3 +27,4 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
27
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
28
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
29
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
data/README.md
CHANGED
@@ -20,7 +20,29 @@ It may be pronounced (lamely) as "excusers".
|
|
20
20
|
|
21
21
|
## Installation
|
22
22
|
|
23
|
-
Install
|
23
|
+
Install via **gem** as in:
|
24
|
+
|
25
|
+
```
|
26
|
+
gem install libclimate-ruby
|
27
|
+
```
|
28
|
+
|
29
|
+
or add it to your `Gemfile`.
|
30
|
+
|
31
|
+
Use is via specific APIs or groups. For example, in order to use the
|
32
|
+
``FrequencyMap`` class you would ``require`` the source file, as in:
|
33
|
+
|
34
|
+
```Ruby
|
35
|
+
require 'xqsr3/containers/frequency_map'
|
36
|
+
```
|
37
|
+
|
38
|
+
Alternatively, to use all **test/unit** extensions you would ``require`` all
|
39
|
+
relatived via the file:
|
40
|
+
|
41
|
+
```Ruby
|
42
|
+
require 'xqsr3/extensions/test/unit'
|
43
|
+
```
|
44
|
+
|
45
|
+
which brings in nine extensions.
|
24
46
|
|
25
47
|
## Components
|
26
48
|
|
@@ -49,6 +71,10 @@ and extensions to the following standard library components:
|
|
49
71
|
* String extensions
|
50
72
|
* test/unit extensions
|
51
73
|
|
74
|
+
## Examples
|
75
|
+
|
76
|
+
Examples are provided in the ```examples``` directory, along with a markdown description for each. A detailed list TOC of them is provided in [EXAMPLES.md](./EXAMPLES.md).
|
77
|
+
|
52
78
|
## Project Information
|
53
79
|
|
54
80
|
### Where to get help
|
@@ -61,17 +87,20 @@ Defect reports, feature requests, and pull requests are welcome on https://githu
|
|
61
87
|
|
62
88
|
### Related projects
|
63
89
|
|
64
|
-
**xqsr3** is a runtime dependency
|
90
|
+
**xqsr3** is a runtime dependency of:
|
65
91
|
|
66
92
|
* the **[libCLImate.Ruby](https://github.com/synesissoftware/libCLImate.Ruby)** library;
|
67
93
|
* the [**xqsr3-xml**](https://github.com/synesissoftware.com/xqsr3-xml/) library.
|
68
94
|
|
69
|
-
and a development dependency
|
95
|
+
and a development dependency of:
|
70
96
|
|
71
97
|
* the **[CLASP.Ruby](https://github.com/synesissoftware/CLASP.Ruby)** library;
|
72
98
|
* the **[cmpfs.Ruby](https://github.com/synesissoftware/cmpfs.Ruby)** library;
|
99
|
+
* the **[libpath.Ruby](https://github.com/synesissoftware/libpath.Ruby)** library;
|
73
100
|
* the **[Pantheios.Ruby](https://github.com/synesissoftware/Pantheios.Ruby)** library.
|
101
|
+
* the **[Quench.Ruby](https://github.com/synesissoftware/Quench.Ruby)** library.
|
74
102
|
|
75
103
|
### License
|
76
104
|
|
77
105
|
**xqsr3** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details.
|
106
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# xqsr3 Example - **count_word_frequencies**
|
2
|
+
|
3
|
+
## Summary
|
4
|
+
|
5
|
+
Simple example illustrating use of ``FrequencyMap`` class.
|
6
|
+
|
7
|
+
## Source
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
|
11
|
+
#!/usr/bin/env ruby
|
12
|
+
|
13
|
+
# examples/count_word_frequencies.rb
|
14
|
+
|
15
|
+
require 'xqsr3/containers/frequency_map'
|
16
|
+
|
17
|
+
include Xqsr3::Containers
|
18
|
+
|
19
|
+
puts "Analyse DATA words via FrequencyMap"
|
20
|
+
puts
|
21
|
+
|
22
|
+
data = DATA.read
|
23
|
+
data = data.gsub(/\n/, ' ')
|
24
|
+
words = data.split
|
25
|
+
|
26
|
+
|
27
|
+
puts "1. Manually (showing items with 2+ occurrences):"
|
28
|
+
|
29
|
+
fm = FrequencyMap.new
|
30
|
+
|
31
|
+
words.each { |word| fm << word }
|
32
|
+
|
33
|
+
fm.each_by_frequency do |word, frequency|
|
34
|
+
|
35
|
+
next if 1 == frequency
|
36
|
+
|
37
|
+
$stdout.puts "\t#{word}\t#{frequency}"
|
38
|
+
end
|
39
|
+
puts
|
40
|
+
|
41
|
+
|
42
|
+
puts "2. Via ByElement (showing items with 2+ occurrences):"
|
43
|
+
|
44
|
+
fm = FrequencyMap::ByElement[*words]
|
45
|
+
|
46
|
+
fm.each_by_frequency do |word, frequency|
|
47
|
+
|
48
|
+
next if 1 == frequency
|
49
|
+
|
50
|
+
$stdout.puts "\t#{word}\t#{frequency}"
|
51
|
+
end
|
52
|
+
puts
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
__END__
|
57
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
58
|
+
```
|
59
|
+
|
60
|
+
The code is pretty self-explanatory. I've grabbed some **Lorem Ipsum** and placed into an ``__END__`` section, which is then read (via ``DATA``) and ``split`` into ``words``. These words are then pushed into ``FrequencyMap`` instances in two ways: manually; and via ``FrequencyMap::ByElement``. Each list is written out, omitting single occurrences, inside an ``each_by_frequency`` loop.
|
61
|
+
|
62
|
+
## Usage
|
63
|
+
|
64
|
+
When run, this produces the following output:
|
65
|
+
|
66
|
+
```
|
67
|
+
Analyse DATA words via FrequencyMap
|
68
|
+
|
69
|
+
1. Manually (showing items with 2+ occurrences):
|
70
|
+
in 3
|
71
|
+
dolor 2
|
72
|
+
dolore 2
|
73
|
+
ut 2
|
74
|
+
|
75
|
+
2. Via ByElement (showing items with 2+ occurrences):
|
76
|
+
in 3
|
77
|
+
dolor 2
|
78
|
+
dolore 2
|
79
|
+
ut 2
|
80
|
+
```
|
81
|
+
|
82
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# examples/count_word_frequencies.rb
|
4
|
+
|
5
|
+
require 'xqsr3/containers/frequency_map'
|
6
|
+
|
7
|
+
include Xqsr3::Containers
|
8
|
+
|
9
|
+
|
10
|
+
puts "Analyse DATA words via FrequencyMap"
|
11
|
+
puts
|
12
|
+
|
13
|
+
data = DATA.read
|
14
|
+
data = data.gsub(/\n/, ' ')
|
15
|
+
words = data.split
|
16
|
+
|
17
|
+
|
18
|
+
puts "1. Manually (showing items with 2+ occurrences):"
|
19
|
+
|
20
|
+
fm = FrequencyMap.new
|
21
|
+
|
22
|
+
words.each { |word| fm << word }
|
23
|
+
|
24
|
+
fm.each_by_frequency do |word, frequency|
|
25
|
+
|
26
|
+
next if 1 == frequency
|
27
|
+
|
28
|
+
$stdout.puts "\t#{word}\t#{frequency}"
|
29
|
+
end
|
30
|
+
puts
|
31
|
+
|
32
|
+
|
33
|
+
puts "2. Via ByElement (showing items with 2+ occurrences):"
|
34
|
+
|
35
|
+
fm = FrequencyMap::ByElement[*words]
|
36
|
+
|
37
|
+
fm.each_by_frequency do |word, frequency|
|
38
|
+
|
39
|
+
next if 1 == frequency
|
40
|
+
|
41
|
+
$stdout.puts "\t#{word}\t#{frequency}"
|
42
|
+
end
|
43
|
+
puts
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
__END__
|
48
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
49
|
+
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 7th December 2017
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
@@ -64,7 +64,7 @@ module JoinWithOr
|
|
64
64
|
#
|
65
65
|
# === Signature
|
66
66
|
#
|
67
|
-
# * *Parameters
|
67
|
+
# * *Parameters:*
|
68
68
|
#
|
69
69
|
# * *Required parameters*:
|
70
70
|
# - +ar+:: [Array] The array whose contents are to be joined
|
@@ -73,7 +73,7 @@ module JoinWithOr
|
|
73
73
|
# - +options+:: [Hash] Options that control the behaviour of the
|
74
74
|
# method
|
75
75
|
#
|
76
|
-
# * *Options
|
76
|
+
# * *Options:*
|
77
77
|
#
|
78
78
|
# - +:or+:: [String] A string that is used instead of 'or'
|
79
79
|
# - +:oxford_comma+:: [boolean] Determines whether an Oxford comma
|
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: FrequencyMap container
|
6
6
|
#
|
7
7
|
# Created: 28th January 2005
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2005-
|
14
|
+
# Copyright (c) 2005-2019, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -44,8 +44,7 @@
|
|
44
44
|
# ######################################################################## #
|
45
45
|
|
46
46
|
|
47
|
-
|
48
|
-
# ::Xqsr3::Containers::FrequencyMap
|
47
|
+
require 'xqsr3/diagnostics/inspect_builder'
|
49
48
|
|
50
49
|
=begin
|
51
50
|
=end
|
@@ -53,10 +52,29 @@
|
|
53
52
|
module Xqsr3
|
54
53
|
module Containers
|
55
54
|
|
55
|
+
# Hash-like class that counts, as the map's values, the frequencies of
|
56
|
+
# elements, as the map's keys
|
56
57
|
class FrequencyMap
|
57
58
|
|
58
59
|
include Enumerable
|
60
|
+
include ::Xqsr3::Diagnostics::InspectBuilder
|
59
61
|
|
62
|
+
# Class that provides a Hash[]-like syntax as follows:
|
63
|
+
#
|
64
|
+
# fm = FrequencyMap::ByElement[ 'abc', 'def', 'abc', :x, 'x', :y ]
|
65
|
+
#
|
66
|
+
# fm.empty? # => false
|
67
|
+
# fm.size # => 5
|
68
|
+
# fm.count # => 6
|
69
|
+
# fm['abc'] # => 2
|
70
|
+
# fm['def'] # => 1
|
71
|
+
# fm['ghi'] # => 0
|
72
|
+
# fm['x'] # => 1
|
73
|
+
# fm['y'] # => 0
|
74
|
+
# fm['z'] # => 0
|
75
|
+
# fm[:x] # => 1
|
76
|
+
# fm[:y] # => 1
|
77
|
+
# fm[:z] # => 0
|
60
78
|
ByElement = Class.new do
|
61
79
|
|
62
80
|
def self.[] *args
|
@@ -71,6 +89,7 @@ class FrequencyMap
|
|
71
89
|
private_class_method :new
|
72
90
|
end
|
73
91
|
|
92
|
+
# Creates an instance from the given arguments
|
74
93
|
def self.[] *args
|
75
94
|
|
76
95
|
return self.new if 0 == args.length
|
@@ -134,26 +153,38 @@ class FrequencyMap
|
|
134
153
|
end
|
135
154
|
end
|
136
155
|
|
156
|
+
# Initialises an instance
|
137
157
|
def initialize
|
138
158
|
|
139
|
-
@
|
159
|
+
@elements = {}
|
140
160
|
@count = 0
|
141
161
|
end
|
142
162
|
|
163
|
+
# Pushes an element into the map, assigning it an initial count of 1
|
164
|
+
#
|
165
|
+
# * *Parameters:*
|
166
|
+
# - +key+:: The element to insert
|
143
167
|
def << key
|
144
168
|
|
145
169
|
push key, 1
|
146
170
|
end
|
147
171
|
|
172
|
+
# Compares the instance for equality against +rhs+
|
173
|
+
#
|
174
|
+
# * *Parameters:*
|
175
|
+
# - +rhs+ (+nil+, +::Hash+, +FrequencyMap+) The instance to compare against
|
176
|
+
#
|
177
|
+
# * *Exceptions:*
|
178
|
+
# - +::TypeError+ if +rhs+ is not of the required type(s)
|
148
179
|
def == rhs
|
149
180
|
|
150
181
|
case rhs
|
151
182
|
when ::NilClass
|
152
183
|
return false
|
153
184
|
when ::Hash
|
154
|
-
return rhs.size == @
|
185
|
+
return rhs.size == @elements.size && rhs == @elements
|
155
186
|
when self.class
|
156
|
-
return rhs.count == self.count && rhs == @
|
187
|
+
return rhs.count == self.count && rhs == @elements
|
157
188
|
else
|
158
189
|
raise TypeError, "can compare #{self.class} only to instances of #{self.class} and #{::Hash}, but #{rhs.class} given"
|
159
190
|
end
|
@@ -161,24 +192,41 @@ class FrequencyMap
|
|
161
192
|
false
|
162
193
|
end
|
163
194
|
|
195
|
+
# Obtains the count for a given key, or +nil+ if the key does not exist
|
196
|
+
#
|
197
|
+
# * *Parameters:*
|
198
|
+
# - +key+ The key to lookup
|
164
199
|
def [] key
|
165
200
|
|
166
|
-
@
|
201
|
+
@elements[key] || 0
|
167
202
|
end
|
168
203
|
|
204
|
+
# Assigns a key and a count
|
205
|
+
#
|
206
|
+
# * *Parameters:*
|
207
|
+
# - +key+ The key to lookup
|
208
|
+
# - +count+ (::Integer) The count to lookup
|
209
|
+
#
|
210
|
+
# * *Exceptions:*
|
211
|
+
# - +::TypeError+ if +count+ is not an +::Integer+
|
169
212
|
def []= key, count
|
170
213
|
|
214
|
+
raise TypeError, "'count' parameter must be of type #{::Integer}, but was of type #{count.class}" unless Integer === count
|
215
|
+
|
171
216
|
store key, count
|
172
217
|
end
|
173
218
|
|
219
|
+
# Searches the instance comparing each element with +key+, returning the
|
220
|
+
# count if found, or +nil+ if not
|
174
221
|
def assoc key
|
175
222
|
|
176
|
-
@
|
223
|
+
@elements.assoc key
|
177
224
|
end
|
178
225
|
|
226
|
+
# Removes all elements from the instance
|
179
227
|
def clear
|
180
228
|
|
181
|
-
@
|
229
|
+
@elements.clear
|
182
230
|
@count = 0
|
183
231
|
end
|
184
232
|
|
@@ -188,18 +236,24 @@ class FrequencyMap
|
|
188
236
|
@count
|
189
237
|
end
|
190
238
|
|
239
|
+
# Obtains the default value of the instance, which will always be +nil+
|
191
240
|
def default
|
192
241
|
|
193
|
-
@
|
242
|
+
@elements.default
|
194
243
|
end
|
195
244
|
|
245
|
+
# Deletes the element with the given +key+ and its counts
|
246
|
+
#
|
247
|
+
# * *Parameters:*
|
248
|
+
# - +key+ The key to delete
|
196
249
|
def delete key
|
197
250
|
|
198
|
-
key_count = @
|
251
|
+
key_count = @elements.delete key
|
199
252
|
|
200
253
|
@count -= key_count if key_count
|
201
254
|
end
|
202
255
|
|
256
|
+
# Duplicates the instance
|
203
257
|
def dup
|
204
258
|
|
205
259
|
fm = self.class.new
|
@@ -207,9 +261,14 @@ class FrequencyMap
|
|
207
261
|
fm.merge! self
|
208
262
|
end
|
209
263
|
|
264
|
+
# Calls _block_ once for each element in the instance, passing the element
|
265
|
+
# and its frequency as parameters. If no block is provided, an enumerator
|
266
|
+
# is returned
|
210
267
|
def each
|
211
268
|
|
212
|
-
@
|
269
|
+
return @elements.each unless block_given?
|
270
|
+
|
271
|
+
@elements.each do |k, v|
|
213
272
|
|
214
273
|
yield k, v
|
215
274
|
end
|
@@ -221,9 +280,9 @@ class FrequencyMap
|
|
221
280
|
# keys must be created and sorted from which enumeration is directed
|
222
281
|
def each_by_key
|
223
282
|
|
224
|
-
@
|
283
|
+
@elements.keys.sort.each do |key|
|
225
284
|
|
226
|
-
yield key, @
|
285
|
+
yield key, @elements[key]
|
227
286
|
end
|
228
287
|
end
|
229
288
|
|
@@ -235,7 +294,7 @@ class FrequencyMap
|
|
235
294
|
def each_by_frequency
|
236
295
|
|
237
296
|
tm = {}
|
238
|
-
@
|
297
|
+
@elements.each do |element, frequency|
|
239
298
|
|
240
299
|
tm[frequency] = [] unless tm.has_key?(frequency)
|
241
300
|
|
@@ -253,8 +312,12 @@ class FrequencyMap
|
|
253
312
|
end
|
254
313
|
end
|
255
314
|
|
315
|
+
# Calls _block_ once for each element in the instance, passing the
|
316
|
+
# element. If no block is provided, an enumerator is returned
|
256
317
|
def each_key
|
257
318
|
|
319
|
+
return @elements.each_key unless block_given?
|
320
|
+
|
258
321
|
keys.each do |element|
|
259
322
|
|
260
323
|
yield element
|
@@ -263,19 +326,26 @@ class FrequencyMap
|
|
263
326
|
|
264
327
|
alias each_pair each
|
265
328
|
|
329
|
+
# Calls _block_ once for each element in the instance, passing the
|
330
|
+
# count. If no block is provided, an enumerator is returned
|
266
331
|
def each_value
|
267
332
|
|
333
|
+
return @elements.each_value unless block_given?
|
334
|
+
|
268
335
|
keys.each do |element|
|
269
336
|
|
270
|
-
yield @
|
337
|
+
yield @elements[element]
|
271
338
|
end
|
272
339
|
end
|
273
340
|
|
341
|
+
# Returns +true+ if instance contains no elements; +false+ otherwise
|
274
342
|
def empty?
|
275
343
|
|
276
344
|
0 == size
|
277
345
|
end
|
278
346
|
|
347
|
+
# Returns +true+ if +rhs+ is an instance of +FrequencyMap+ and contains
|
348
|
+
# the same elements and their counts; +false+ otherwise
|
279
349
|
def eql? rhs
|
280
350
|
|
281
351
|
case rhs
|
@@ -286,6 +356,11 @@ class FrequencyMap
|
|
286
356
|
end
|
287
357
|
end
|
288
358
|
|
359
|
+
# Returns the count from the instance for the given element +key+. If
|
360
|
+
# +key+ cannot be found, there are several options: with no other
|
361
|
+
# arguments, it will raise a +::KeyError+ exception; if +default+ is
|
362
|
+
# given, then that will be returned; if the optional code block is
|
363
|
+
# specified, then that will be run and its result returned
|
289
364
|
def fetch key, default = nil, &block
|
290
365
|
|
291
366
|
case default
|
@@ -295,7 +370,7 @@ class FrequencyMap
|
|
295
370
|
raise TypeError, "default parameter ('#{default}') must be of type #{::Integer}, but was of type #{default.class}"
|
296
371
|
end
|
297
372
|
|
298
|
-
unless @
|
373
|
+
unless @elements.has_key? key
|
299
374
|
|
300
375
|
return default unless default.nil?
|
301
376
|
|
@@ -314,19 +389,24 @@ class FrequencyMap
|
|
314
389
|
raise KeyError, "given key '#{key}' (#{key.class}) does not exist"
|
315
390
|
end
|
316
391
|
|
317
|
-
@
|
392
|
+
@elements[key]
|
318
393
|
end
|
319
394
|
|
395
|
+
# Returns the equivalent flattened form of the instance
|
320
396
|
def flatten
|
321
397
|
|
322
|
-
@
|
398
|
+
@elements.flatten
|
323
399
|
end
|
324
400
|
|
401
|
+
# Returns +true+ if an element with the given +key+ is in the map; +false+
|
402
|
+
# otherwise
|
325
403
|
def has_key? key
|
326
404
|
|
327
|
-
@
|
405
|
+
@elements.has_key? key
|
328
406
|
end
|
329
407
|
|
408
|
+
# Returns +true+ if an element with a count of the given +value+ is in the
|
409
|
+
# map; +false+ otherwise
|
330
410
|
def has_value? value
|
331
411
|
|
332
412
|
case value
|
@@ -336,52 +416,63 @@ class FrequencyMap
|
|
336
416
|
raise TypeError, "parameter ('#{value}') must be of type #{::Integer}, but was of type #{value.class}"
|
337
417
|
end
|
338
418
|
|
339
|
-
@
|
419
|
+
@elements.has_value? value
|
340
420
|
end
|
341
421
|
|
422
|
+
# A hash-code for this instance
|
342
423
|
def hash
|
343
424
|
|
344
|
-
@
|
425
|
+
@elements.hash
|
345
426
|
end
|
346
427
|
|
347
428
|
alias include? has_key?
|
348
429
|
|
430
|
+
# A diagnostics string form of the instance
|
349
431
|
def inspect
|
350
432
|
|
351
|
-
|
433
|
+
make_inspect show_fields: true
|
352
434
|
end
|
353
435
|
|
354
436
|
# def keep_if
|
355
437
|
#
|
356
|
-
# @
|
438
|
+
# @elements.keep_if
|
357
439
|
# end
|
358
440
|
|
359
|
-
|
441
|
+
# Returns the element that has the given count, or +nil+ if none found
|
442
|
+
#
|
443
|
+
# * *Parameters:*
|
444
|
+
# - +count+ (::Integer) The count to lookup
|
445
|
+
#
|
446
|
+
# * *Exceptions:*
|
447
|
+
# - +::TypeError+ if +count+ is not of the required type(s)
|
448
|
+
def key count
|
360
449
|
|
361
|
-
|
362
|
-
when ::NilClass, ::Integer
|
363
|
-
;
|
364
|
-
else
|
365
|
-
raise TypeError, "parameter ('#{value}') must be of type #{::Integer}, but was of type #{value.class}"
|
366
|
-
end
|
450
|
+
raise TypeError, "'count' parameter must be of type #{::Integer}, but was of type #{count.class}" unless Integer === count
|
367
451
|
|
368
|
-
@
|
452
|
+
@elements.key count
|
369
453
|
end
|
370
454
|
|
371
455
|
alias key? has_key?
|
372
456
|
|
457
|
+
# An array of the elements only
|
373
458
|
def keys
|
374
459
|
|
375
|
-
@
|
460
|
+
@elements.keys
|
376
461
|
end
|
377
462
|
|
463
|
+
# The number of elements in the map
|
378
464
|
def length
|
379
465
|
|
380
|
-
@
|
466
|
+
@elements.length
|
381
467
|
end
|
382
468
|
|
383
469
|
alias member? has_key?
|
384
470
|
|
471
|
+
# Returns a new instance containing a merging of the current instance and
|
472
|
+
# the +fm+ instance
|
473
|
+
#
|
474
|
+
# NOTE: where any element is found in both merging instances the count
|
475
|
+
# will be a combination of the two counts
|
385
476
|
def merge fm
|
386
477
|
|
387
478
|
raise TypeError, "parameter must be an instance of type #{self.class}" unless fm.instance_of? self.class
|
@@ -394,16 +485,20 @@ class FrequencyMap
|
|
394
485
|
fm_new
|
395
486
|
end
|
396
487
|
|
488
|
+
# Merges the contents of +fm+ into the current instance
|
489
|
+
#
|
490
|
+
# NOTE: where any element is found in both merging instances the count
|
491
|
+
# will be a combination of the two counts
|
397
492
|
def merge! fm
|
398
493
|
|
399
494
|
fm.each do |k, v|
|
400
495
|
|
401
|
-
if not @
|
496
|
+
if not @elements.has_key? k
|
402
497
|
|
403
|
-
@
|
498
|
+
@elements[k] = v
|
404
499
|
else
|
405
500
|
|
406
|
-
@
|
501
|
+
@elements[k] += v
|
407
502
|
end
|
408
503
|
@count += v
|
409
504
|
end
|
@@ -411,16 +506,34 @@ class FrequencyMap
|
|
411
506
|
self
|
412
507
|
end
|
413
508
|
|
414
|
-
|
509
|
+
# Pushes the +element+ and +count+. If the +element+ already exists,
|
510
|
+
# +count+ will be added to the existing count; otherwise it will be
|
511
|
+
# +count+
|
512
|
+
#
|
513
|
+
# === Signature
|
514
|
+
#
|
515
|
+
# * *Parameters:*
|
516
|
+
# - +key+ The element key
|
517
|
+
# - +count+ (Integer) The count by which to adjust
|
518
|
+
#
|
519
|
+
# === Exceptions
|
520
|
+
# - +::RangeError+ raised if the value of +count+ results in a negative count for the given element
|
521
|
+
# - +::TypeError+ if +count+ is not an +::Integer+
|
522
|
+
def push key, count = 1
|
523
|
+
|
524
|
+
raise TypeError, "'count' parameter must be of type #{::Integer}, but was of type #{count.class}" unless Integer === count
|
525
|
+
|
526
|
+
initial_count = @elements[key] || 0
|
527
|
+
resulting_count = initial_count + count
|
415
528
|
|
416
|
-
raise
|
529
|
+
raise RangeError, "count for element '#{key}' cannot be made negative" if resulting_count < 0
|
417
530
|
|
418
|
-
if
|
531
|
+
if 0 == resulting_count
|
419
532
|
|
420
|
-
@
|
533
|
+
@elements.delete key
|
421
534
|
else
|
422
535
|
|
423
|
-
@
|
536
|
+
@elements[key] = resulting_count
|
424
537
|
end
|
425
538
|
@count += count
|
426
539
|
|
@@ -429,7 +542,7 @@ class FrequencyMap
|
|
429
542
|
|
430
543
|
def shift
|
431
544
|
|
432
|
-
r = @
|
545
|
+
r = @elements.shift
|
433
546
|
|
434
547
|
@count -= r[1] if ::Array === r
|
435
548
|
|
@@ -438,42 +551,52 @@ class FrequencyMap
|
|
438
551
|
|
439
552
|
alias size length
|
440
553
|
|
441
|
-
|
554
|
+
# Causes an element with the given +key+ and +count+ to be stored. If an
|
555
|
+
# element with the given +key+ already exists, its count will be adjusted,
|
556
|
+
# as will the total count
|
557
|
+
#
|
558
|
+
# === Return
|
559
|
+
# +true+ if the element was inserted; +false+ if the element was
|
560
|
+
# overwritten
|
561
|
+
def store key, count
|
442
562
|
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
else
|
447
|
-
raise TypeError, "value ('#{value}') must be of type #{::Integer}, but was of type #{value.class}"
|
448
|
-
end
|
563
|
+
raise TypeError, "'count' parameter must be of type #{::Integer}, but was of type #{count.class}" unless Integer === count
|
564
|
+
|
565
|
+
old_count = @elements[key] || 0
|
449
566
|
|
450
|
-
|
567
|
+
@elements.store key, count
|
451
568
|
|
452
|
-
@
|
569
|
+
@count += count - old_count
|
453
570
|
|
454
|
-
|
571
|
+
old_count == 0
|
455
572
|
end
|
456
573
|
|
574
|
+
# Converts instance to an array of +[key,value]+ pairs
|
457
575
|
def to_a
|
458
576
|
|
459
|
-
@
|
577
|
+
@elements.to_a
|
460
578
|
end
|
461
579
|
|
580
|
+
# Obtains reference to internal hash instance (which must *not* be modified)
|
462
581
|
def to_h
|
463
582
|
|
464
|
-
@
|
583
|
+
@elements.to_h
|
465
584
|
end
|
466
585
|
|
586
|
+
# Obtains equivalent hash to instance
|
467
587
|
def to_hash
|
468
588
|
|
469
|
-
@
|
589
|
+
@elements.to_hash
|
470
590
|
end
|
471
591
|
|
472
|
-
|
592
|
+
def to_s
|
593
|
+
|
594
|
+
@elements.to_s
|
595
|
+
end
|
473
596
|
|
474
597
|
def values
|
475
598
|
|
476
|
-
@
|
599
|
+
@elements.values
|
477
600
|
end
|
478
601
|
end # class FrequencyMap
|
479
602
|
|
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: multimap container
|
6
6
|
#
|
7
7
|
# Created: 21st March 2007
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2007-
|
14
|
+
# Copyright (c) 2007-2019, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -202,6 +202,8 @@ class MultiMap < ::Hash
|
|
202
202
|
|
203
203
|
def each_key
|
204
204
|
|
205
|
+
return @inner.each_key unless block_given?
|
206
|
+
|
205
207
|
@inner.each_key { |key| yield key }
|
206
208
|
end
|
207
209
|
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 3rd June 2017
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2017, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -77,10 +77,10 @@ module BoolParser
|
|
77
77
|
#
|
78
78
|
# === Signature
|
79
79
|
#
|
80
|
-
# * *Parameters
|
80
|
+
# * *Parameters:*
|
81
81
|
# - +options+:: An options hash, containing any of the following options
|
82
82
|
#
|
83
|
-
# * *Options
|
83
|
+
# * *Options:*
|
84
84
|
# - +:false_values+:: [::Array] An array of strings or regular
|
85
85
|
# expressions against which to match for false value. Defaults to
|
86
86
|
# +DEFAULT_FALSE_VALUES+
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 21st November 2017
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2017-
|
15
|
+
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -155,7 +155,7 @@ module IntegerParser
|
|
155
155
|
#
|
156
156
|
# === Signature
|
157
157
|
#
|
158
|
-
# * *Parameters
|
158
|
+
# * *Parameters:*
|
159
159
|
# - +arg+:: The argument to be converted (to +Fixnum+ or +Bignum+)
|
160
160
|
# - +base+:: A value of 0, or between 2 and 36. Defaults to 0
|
161
161
|
# - +options+:: An options hash, containing any of the following
|
@@ -166,7 +166,7 @@ module IntegerParser
|
|
166
166
|
# take additional action. If the block returns then its return value
|
167
167
|
# will be returned to the caller
|
168
168
|
#
|
169
|
-
# * *Options
|
169
|
+
# * *Options:*
|
170
170
|
# - +:default+:: A default value to be used when +arg+ is +nil+ or
|
171
171
|
# cannot be converted by (the original) +Kernel#Integer+
|
172
172
|
# - +:nil+:: Returns +nil+ if +arg+ is +nil+ or cannot be
|
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Adds a unique() method to the Enumerable module
|
6
6
|
#
|
7
7
|
# Created: 5th March 2007
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2007-
|
14
|
+
# Copyright (c) 2007-2019, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -55,6 +55,9 @@ module Enumerable
|
|
55
55
|
# Removes all duplicate elements in a sequence subject to an optional
|
56
56
|
# two-parameter block in order to return an array containing unique
|
57
57
|
# elements
|
58
|
+
#
|
59
|
+
# [ 1, 2, 3 ].unique # => [ 1, 2, 3 ]
|
60
|
+
# [ 1, 2, 1, 3 ].unique # => [ 1, 2, 3 ]
|
58
61
|
def unique(&block)
|
59
62
|
|
60
63
|
if not block
|
@@ -62,38 +65,25 @@ module Enumerable
|
|
62
65
|
return unique { |a, b| a == b }
|
63
66
|
else
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
raise ArgumentError, "block requires two parameters"
|
68
|
-
end
|
68
|
+
raise ArgumentError, "block requires two parameters" unless block.arity == 2
|
69
69
|
|
70
70
|
ar = self.to_a
|
71
71
|
|
72
72
|
return ar if ar.length < 2
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
i = 0
|
77
|
-
|
78
|
-
while i < ar.length do
|
74
|
+
r = []
|
75
|
+
h = {}
|
79
76
|
|
80
|
-
|
77
|
+
ar.each do |v|
|
81
78
|
|
82
|
-
|
79
|
+
unless h.has_key?(v)
|
83
80
|
|
84
|
-
|
85
|
-
|
86
|
-
ar.delete_at(j)
|
87
|
-
else
|
88
|
-
|
89
|
-
j = j + 1
|
90
|
-
end
|
81
|
+
r << v
|
82
|
+
h[v] = nil
|
91
83
|
end
|
92
|
-
|
93
|
-
i = i + 1
|
94
84
|
end
|
95
85
|
|
96
|
-
return
|
86
|
+
return r
|
97
87
|
end
|
98
88
|
end
|
99
89
|
end # module Enumerable
|
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Adds a Integer 'overload' to the Kernel module
|
6
6
|
#
|
7
7
|
# Created: 21st November 2017
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2017-
|
14
|
+
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -60,7 +60,7 @@ module Kernel
|
|
60
60
|
#
|
61
61
|
# === Signature
|
62
62
|
#
|
63
|
-
# * *Parameters
|
63
|
+
# * *Parameters:*
|
64
64
|
# - +arg+:: The argument to be converted (to +Fixnum+ or +Bignum+)
|
65
65
|
# - +base+:: A value of 0, or between 2 and 36. Defaults to 0
|
66
66
|
# - +options+:: An options hash, containing any of the following
|
@@ -70,7 +70,7 @@ module Kernel
|
|
70
70
|
# additional action. If the block returns then its return value will
|
71
71
|
# be returned to the caller
|
72
72
|
#
|
73
|
-
# * *Options
|
73
|
+
# * *Options:*
|
74
74
|
# - +:default+:: A default value to be used when +arg+ is +nil+ or
|
75
75
|
# cannot be converted by (the original) +Kernel#Integer+
|
76
76
|
# - +:nil+:: Returns +nil+ if +arg+ is +nil+ or cannot be
|
data/lib/xqsr3/io/writelines.rb
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
# Purpose: Adds a writelines() method to the IO module
|
6
6
|
#
|
7
7
|
# Created: 13th April 2007
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
-
# Copyright (c) 2007-
|
14
|
+
# Copyright (c) 2007-2019, Matthew Wilson and Synesis Software
|
15
15
|
# All rights reserved.
|
16
16
|
#
|
17
17
|
# Redistribution and use in source and binary forms, with or without
|
@@ -125,12 +125,12 @@ $stderr.puts "#{self.class}.write_to_target_(target(#{target.class})='#{target}'
|
|
125
125
|
#
|
126
126
|
# === Signature
|
127
127
|
#
|
128
|
-
# * *Parameters
|
128
|
+
# * *Parameters:*
|
129
129
|
# - +target+:: The target of the write, which may be a string containing the path or a stream instance that supports write
|
130
130
|
# - +contents+:: The contents to be write, which may be a +Hash+, or an +Array+, or a +String+ containing delimited fields
|
131
131
|
# - +options+:: An options hash, containing any of the following options
|
132
132
|
#
|
133
|
-
# * *Options
|
133
|
+
# * *Options:*
|
134
134
|
# - +:column_separator+:: {optional} The column separator, to be applied between each field in the case where +contents+ is a +Hash+.
|
135
135
|
# - +:eol_lookahead_limit+:: {optional} The number of content elements (line/pair) to inspect to determine whether element has a terminating end-of-line sequence. Defaults to 20. If 0, and +:line_separator+ is not specified, then will default to <tt>"\n"</tt>. If +nil+, then every line will be inspected.
|
136
136
|
# - +:line_separator+:: {optional} The line separator, to be applied to the end of line created from each entry. When not specified, it will be deduced by inspecting +contents+ (according to +eol_lookahead_limit+).
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 13th April 2016
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2016, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2016-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -114,7 +114,7 @@ module EndsWith
|
|
114
114
|
#
|
115
115
|
# === Signature
|
116
116
|
#
|
117
|
-
# * *Parameters
|
117
|
+
# * *Parameters:*
|
118
118
|
#
|
119
119
|
# * *Required parameters*:
|
120
120
|
# - +s+:: [String] The string to be evaluated
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 25th January 2018
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2018, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2018-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -73,7 +73,7 @@ module NilIfEmpty
|
|
73
73
|
#
|
74
74
|
# === Signature
|
75
75
|
#
|
76
|
-
# * *Parameters
|
76
|
+
# * *Parameters:*
|
77
77
|
#
|
78
78
|
# * *Required parameters*:
|
79
79
|
# - +s+:: [String] The string to be evaluated
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 25th January 2018
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2018, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2018-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -73,7 +73,7 @@ module NilIfWhitespace
|
|
73
73
|
#
|
74
74
|
# === Signature
|
75
75
|
#
|
76
|
-
# * *Parameters
|
76
|
+
# * *Parameters:*
|
77
77
|
#
|
78
78
|
# * *Required parameters*:
|
79
79
|
# - +s+:: [String] The string to be evaluated
|
@@ -6,13 +6,13 @@
|
|
6
6
|
# module
|
7
7
|
#
|
8
8
|
# Created: 3rd June 2017
|
9
|
-
# Updated:
|
9
|
+
# Updated: 12th April 2019
|
10
10
|
#
|
11
11
|
# Home: http://github.com/synesissoftware/xqsr3
|
12
12
|
#
|
13
13
|
# Author: Matthew Wilson
|
14
14
|
#
|
15
|
-
# Copyright (c) 2017, Matthew Wilson and Synesis Software
|
15
|
+
# Copyright (c) 2017-2019, Matthew Wilson and Synesis Software
|
16
16
|
# All rights reserved.
|
17
17
|
#
|
18
18
|
# Redistribution and use in source and binary forms, with or without
|
@@ -92,7 +92,7 @@ module QuoteIf
|
|
92
92
|
#
|
93
93
|
# === Signature
|
94
94
|
#
|
95
|
-
# * *Parameters
|
95
|
+
# * *Parameters:*
|
96
96
|
#
|
97
97
|
# * *Required parameters*:
|
98
98
|
# - +s+:: [String] The string to be evaluated
|
@@ -101,7 +101,7 @@ module QuoteIf
|
|
101
101
|
# - +options+:: [Hash] Options that control the behaviour of the
|
102
102
|
# method
|
103
103
|
#
|
104
|
-
# * *Options
|
104
|
+
# * *Options:*
|
105
105
|
#
|
106
106
|
# - +:quotes+:: [String, Array] A string that is used as the opening
|
107
107
|
# and closing quotes, or an array whose first two elements are
|
data/lib/xqsr3/version.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Purpose: Version for Xqsr3 library
|
6
6
|
#
|
7
7
|
# Created: 3rd April 2016
|
8
|
-
# Updated:
|
8
|
+
# Updated: 12th April 2019
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/xqsr3
|
11
11
|
#
|
@@ -50,7 +50,7 @@
|
|
50
50
|
module Xqsr3
|
51
51
|
|
52
52
|
# Current version of the Xqsr3 library
|
53
|
-
VERSION = '0.
|
53
|
+
VERSION = '0.32.2'
|
54
54
|
|
55
55
|
private
|
56
56
|
VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
|
@@ -18,6 +18,10 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
18
18
|
assert_equal 0, fm1.count
|
19
19
|
assert fm1.empty?
|
20
20
|
assert_equal 0, fm1.size
|
21
|
+
|
22
|
+
assert_nil fm1.default
|
23
|
+
|
24
|
+
assert_match /^#<Xqsr3::Containers::FrequencyMap:0x\d+:\s*@count\(\w+\)=0; @elements\(Hash\)={}\s*>$/, fm1.inspect
|
21
25
|
end
|
22
26
|
|
23
27
|
def test_class_operator_subscript_2
|
@@ -27,6 +31,8 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
27
31
|
assert_equal 3, fm2.count
|
28
32
|
assert_not fm2.empty?
|
29
33
|
assert_equal 2, fm2.size
|
34
|
+
|
35
|
+
assert_match /^#<Xqsr3::Containers::FrequencyMap:0x\d+:\s*@count\(\w+\)=3; @elements\(Hash\)={.*abc.*def.*}\s*>$/, fm2.inspect
|
30
36
|
end
|
31
37
|
|
32
38
|
def test_class_operator_subscript_3
|
@@ -102,6 +108,52 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
102
108
|
assert_equal 2, fm['jkl']
|
103
109
|
end
|
104
110
|
|
111
|
+
def test_class_operator_subscript_9
|
112
|
+
|
113
|
+
fm = FrequencyMap::ByElement[ 'abc', 'def', 'abc', :x, 'x', :y ]
|
114
|
+
|
115
|
+
assert_false fm.empty? # => false
|
116
|
+
assert_equal 5, fm.size # => 5
|
117
|
+
assert_equal 6, fm.count # => 6
|
118
|
+
assert_equal 2, fm['abc'] # => 2
|
119
|
+
assert_equal 1, fm['def'] # => 1
|
120
|
+
assert_equal 0, fm['ghi'] # => 0
|
121
|
+
assert_equal 1, fm['x'] # => 1
|
122
|
+
assert_equal 0, fm['y'] # => 0
|
123
|
+
assert_equal 0, fm['z'] # => 0
|
124
|
+
assert_equal 1, fm[:x] # => 1
|
125
|
+
assert_equal 1, fm[:y] # => 1
|
126
|
+
assert_equal 0, fm[:z] # => 0
|
127
|
+
|
128
|
+
fm.push 'abc'
|
129
|
+
|
130
|
+
assert_false fm.empty?
|
131
|
+
assert_equal 5, fm.size
|
132
|
+
assert_equal 7, fm.count
|
133
|
+
assert_equal 3, fm['abc']
|
134
|
+
|
135
|
+
fm.push 'abc', 2
|
136
|
+
|
137
|
+
assert_false fm.empty?
|
138
|
+
assert_equal 5, fm.size
|
139
|
+
assert_equal 9, fm.count
|
140
|
+
assert_equal 5, fm['abc']
|
141
|
+
|
142
|
+
fm.push 'abc', -4
|
143
|
+
|
144
|
+
assert_false fm.empty?
|
145
|
+
assert_equal 5, fm.size
|
146
|
+
assert_equal 5, fm.count
|
147
|
+
assert_equal 1, fm['abc']
|
148
|
+
|
149
|
+
fm.push 'abc', -1
|
150
|
+
|
151
|
+
assert_false fm.empty?
|
152
|
+
assert_equal 4, fm.size
|
153
|
+
assert_equal 4, fm.count
|
154
|
+
assert_equal 0, fm['abc']
|
155
|
+
end
|
156
|
+
|
105
157
|
def test_instance_operator_equals
|
106
158
|
|
107
159
|
fm1 = FrequencyMap.new
|
@@ -150,13 +202,13 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
150
202
|
|
151
203
|
fm = FrequencyMap.new
|
152
204
|
|
153
|
-
|
154
|
-
|
205
|
+
assert_equal 0, fm[:abc]
|
206
|
+
assert_equal 0, fm[:def]
|
155
207
|
|
156
208
|
fm << :abc
|
157
209
|
|
158
210
|
assert_equal 1, fm[:abc]
|
159
|
-
|
211
|
+
assert_equal 0, fm[:def]
|
160
212
|
|
161
213
|
fm << :def << :def << :def
|
162
214
|
|
@@ -200,7 +252,7 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
200
252
|
|
201
253
|
fm = FrequencyMap.new
|
202
254
|
|
203
|
-
|
255
|
+
assert_equal 0, fm['abc']
|
204
256
|
assert_equal 0, fm.count
|
205
257
|
assert fm.empty?
|
206
258
|
assert_equal 0, fm.size
|
@@ -214,7 +266,7 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
214
266
|
|
215
267
|
fm.clear
|
216
268
|
|
217
|
-
|
269
|
+
assert_equal 0, fm['abc']
|
218
270
|
assert_equal 0, fm.count
|
219
271
|
assert fm.empty?
|
220
272
|
assert_equal 0, fm.size
|
@@ -757,3 +809,4 @@ class Test_Xqsr3_Containers_FrequencyMap < Test::Unit::TestCase
|
|
757
809
|
end
|
758
810
|
end
|
759
811
|
|
812
|
+
|
@@ -43,5 +43,29 @@ class Test_Enumerable_unique_test < Test::Unit::TestCase
|
|
43
43
|
|
44
44
|
assert_equal [ 1, 2, 3, 4], dest
|
45
45
|
end
|
46
|
+
|
47
|
+
def test_unique_very_large_sorted
|
48
|
+
|
49
|
+
max = 100000
|
50
|
+
|
51
|
+
src = (0...max).to_a * 2
|
52
|
+
exp = (0...max).to_a
|
53
|
+
|
54
|
+
dest = src.unique
|
55
|
+
|
56
|
+
assert_equal exp, dest
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_unique_very_large_unsorted
|
60
|
+
|
61
|
+
max = 100000
|
62
|
+
|
63
|
+
src = ((0...max).to_a * 2).sort
|
64
|
+
exp = (0...max).to_a
|
65
|
+
|
66
|
+
dest = src.unique
|
67
|
+
|
68
|
+
assert_equal exp, dest
|
69
|
+
end
|
46
70
|
end
|
47
71
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xqsr3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.32.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Wilson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
eXtensions by fine Quantum for Standard Ruby and 3rd-party libraries is a
|
@@ -21,6 +21,8 @@ extra_rdoc_files: []
|
|
21
21
|
files:
|
22
22
|
- LICENSE
|
23
23
|
- README.md
|
24
|
+
- examples/count_word_frequencies.md
|
25
|
+
- examples/count_word_frequencies.rb
|
24
26
|
- lib/xqsr3/array_utilities/join_with_or.rb
|
25
27
|
- lib/xqsr3/command_line_utilities/map_option_string.rb
|
26
28
|
- lib/xqsr3/containers/frequency_map.rb
|