signed_multiset 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +5 -0
- data/README.md +3 -3
- data/lib/signed_multiset.rb +206 -2
- data/signed_multiset.gemspec +4 -6
- data/test/{signed_multiset/signed_multiset_test.rb → signed_multiset_test.rb} +15 -8
- metadata +7 -11
- data/lib/signed_multiset/signed_multiset.rb +0 -206
- data/lib/signed_multiset/version.rb +0 -3
- data/test/test_helper.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f89a246862b71b53eeb8ee2f38eadfab7a4b90cf
|
4
|
+
data.tar.gz: 30777e6a599eb97385961f21593de03ecd8b0347
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 000bb39cfbed2233c77e35c9d4062a052648fbc1764fba9a892dc4f3c2327ee36dbafae8650be4f934f3ebc60b32ffd8c0cbf2dff432789aaaeb8e8bff458f81
|
7
|
+
data.tar.gz: c9dbf1ca92a7c8dc9905eb119180c7636a61a72e6499176ca95cf7c420bf5d99c3e19130345b341ddaa3f00096ece528699eea76c91fdd267f27a64f771d79ef
|
data/HISTORY.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
- Remove the SignedMultiset folder namespace.
|
3
|
+
- Replace SignedMultiset[] with SignedMultiset()
|
4
|
+
- SignedMultiset() and SignedMultiset.new() both take arrays, hashes, or argument lists as arguments.
|
5
|
+
|
1
6
|
# 0.1.0
|
2
7
|
- Fix return values when setting mutliplicity.
|
3
8
|
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
Signed Multiset is a Ruby implementation of a Multiset that allows negative membership.
|
9
9
|
|
10
|
-
You can think of it as a Multiset or Bag that allows for negative counts. It feels like a Ruby Hash or Array, but with some differences:
|
10
|
+
You can think of it as a Multiset or Bag that allows for negative counts. It's functionality is very similar to Sorted Sets available in Redis (albeit without the storage functionality). It feels like a Ruby Hash or Array, but with some differences:
|
11
11
|
|
12
12
|
- A key (any ruby object) can be added to or removed from the SignedMultiset any number of times. The number of times it is included in the multiset (positive or negative) is referred to as it's multiplicity.
|
13
13
|
|
@@ -65,7 +65,7 @@ set.cardinality
|
|
65
65
|
set.size
|
66
66
|
# => 3
|
67
67
|
|
68
|
-
other_set = SignedMultiset
|
68
|
+
other_set = SignedMultiset(:a, :c, :d, :d)
|
69
69
|
# => <SignedMultiset a: 1, c: 1, d: 2>
|
70
70
|
|
71
71
|
set + other_set
|
@@ -75,7 +75,7 @@ set & other_set
|
|
75
75
|
# => <SignedMultiset c: 1, d: -3>
|
76
76
|
|
77
77
|
set | other_set
|
78
|
-
=> <SignedMultiset b: 2, c: 3, d: 2, a: 1>
|
78
|
+
# => <SignedMultiset b: 2, c: 3, d: 2, a: 1>
|
79
79
|
```
|
80
80
|
|
81
81
|
## Contributing
|
data/lib/signed_multiset.rb
CHANGED
@@ -1,2 +1,206 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
class SignedMultiset
|
2
|
+
VERSION = "0.2.0"
|
3
|
+
|
4
|
+
include Enumerable
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
# Create a new SignedMultiset instance.
|
8
|
+
#
|
9
|
+
# @param object [Enumerable, nil] An array of keys, or key-muliplicity pairs.
|
10
|
+
def initialize(*args)
|
11
|
+
obj = args.count == 1 ? args.first : args
|
12
|
+
if obj.respond_to?(:each)
|
13
|
+
obj.each { |k, v| increment(k, v || 1) }
|
14
|
+
else
|
15
|
+
self << obj
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the non-zero key-multiplicity pairs.
|
20
|
+
#
|
21
|
+
# @return [Hash]
|
22
|
+
def multiplicities
|
23
|
+
entries.reject{|k,v| v == 0}
|
24
|
+
end
|
25
|
+
|
26
|
+
# Iterate over the multiplicity collection.
|
27
|
+
#
|
28
|
+
# @return [Enumerator]
|
29
|
+
def each(*args, &block)
|
30
|
+
if block_given?
|
31
|
+
multiplicities.each { |k,v| yield(k,v) }
|
32
|
+
else
|
33
|
+
multiplicities.each(args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get the multiplicity for a key.
|
38
|
+
#
|
39
|
+
# @param key [Object] The key to get the multiplicity of
|
40
|
+
# @return [Integer, nil] The multiplicity for the key, or nil if the key is
|
41
|
+
# not present, or has a zero multiplicity
|
42
|
+
def [](key)
|
43
|
+
multiplicities[key]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set the multiplicity for a key.
|
47
|
+
#
|
48
|
+
# @param key [Object] The key to set the multiplicity of
|
49
|
+
# @param multiplicity [Integer] The desired multiplicity
|
50
|
+
# @return [Integer] The multiplicity for the key
|
51
|
+
def []=(key, multiplicity)
|
52
|
+
entries[key] = multiplicity
|
53
|
+
self[key]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Increment the multiplicity for a key.
|
57
|
+
#
|
58
|
+
# @param key (see #[]=)
|
59
|
+
# @param value [Integer] The desired increment value, positive or negative
|
60
|
+
# @return (see #[]=)
|
61
|
+
def increment(key, value)
|
62
|
+
entries[key] ||= 0
|
63
|
+
entries[key] += value
|
64
|
+
self[key]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Increment multiplicity by 1 for a key. This method is chainable.
|
68
|
+
#
|
69
|
+
# @param key [Object] The key to increment the multiplicity of
|
70
|
+
# @return [self]
|
71
|
+
def <<(key)
|
72
|
+
increment(key, 1)
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
# Remove key completely from the set, similar to [key]=0
|
77
|
+
#
|
78
|
+
# @param key [Object] The key to remove
|
79
|
+
# @return [Integer] The multiplicity of the item removed.
|
80
|
+
def delete(key)
|
81
|
+
entries.delete(key)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Creates a new instance of equal to current instance
|
85
|
+
# @return [SignedMultiset]
|
86
|
+
def dup
|
87
|
+
self.class.new(multiplicities)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Combine self with another SignedMultiset via addition to create a merged instance.
|
91
|
+
#
|
92
|
+
# @param other [SignedMultiset]
|
93
|
+
# @return [SignedMultiset]
|
94
|
+
def +(other)
|
95
|
+
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
96
|
+
m.increment(k,v); m
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Combine self with another SignedMultiset via subtraction to create a merged instance.
|
101
|
+
#
|
102
|
+
# @param other (see #+)
|
103
|
+
# @return (see #+)
|
104
|
+
def -(other)
|
105
|
+
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
106
|
+
m.increment(k,-v); m
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Combine self with another SignedMultiset via union to create a merged instance.
|
111
|
+
#
|
112
|
+
# @param other (see #+)
|
113
|
+
# @return (see #+)
|
114
|
+
def |(other)
|
115
|
+
(keys | other.keys).reduce(self.class.new) do |m, k|
|
116
|
+
m.increment(k, [self[k] || 0, other[k] || 0].max); m
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Combine self with another SignedMultiset via intersection to create a merged instance.
|
121
|
+
#
|
122
|
+
# @param other (see #+)
|
123
|
+
# @return (see #+)
|
124
|
+
def &(other)
|
125
|
+
(keys & other.keys).reduce(self.class.new) do |m, k|
|
126
|
+
m.increment(k, [self[k], other[k]].min); m
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Get the list of keys for self.
|
131
|
+
#
|
132
|
+
# @return [Array]
|
133
|
+
def keys
|
134
|
+
multiplicities.keys
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get the multiplicity values for self.
|
138
|
+
#
|
139
|
+
# @return [Array]
|
140
|
+
def values
|
141
|
+
multiplicities.values
|
142
|
+
end
|
143
|
+
|
144
|
+
# Get the cardinality (sum of multiplicities) for self.
|
145
|
+
#
|
146
|
+
# @return [Integer]
|
147
|
+
def cardinality
|
148
|
+
values.inject(&:+)
|
149
|
+
end
|
150
|
+
alias_method :sum, :cardinality
|
151
|
+
|
152
|
+
# Get the count of unique keys in the SignedMultiset.
|
153
|
+
#
|
154
|
+
# @return [Integer]
|
155
|
+
def size
|
156
|
+
keys.size
|
157
|
+
end
|
158
|
+
alias_method :length, :size
|
159
|
+
|
160
|
+
# Compare self with another SignedMultiset
|
161
|
+
#
|
162
|
+
# @param other (see #+)
|
163
|
+
# @return [-1,0,1]
|
164
|
+
def <=>(other)
|
165
|
+
if [:multiplicities, :cardinality, :size].all? { |m| other.respond_to?(m) }
|
166
|
+
if multiplicities == other.multiplicities
|
167
|
+
0
|
168
|
+
elsif cardinality != other.cardinality
|
169
|
+
cardinality <=> other.cardinality
|
170
|
+
elsif size != other.size
|
171
|
+
size <=> other.size
|
172
|
+
else
|
173
|
+
multiplicities <=> other.multiplicities
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_hash
|
179
|
+
multiplicities.dup
|
180
|
+
end
|
181
|
+
|
182
|
+
def to_a
|
183
|
+
multiplicities.to_a
|
184
|
+
end
|
185
|
+
|
186
|
+
def to_s
|
187
|
+
multiplicities.map{ |k,m| "#{k}: #{m}"}.join(', ')
|
188
|
+
end
|
189
|
+
|
190
|
+
def inspect
|
191
|
+
"<#{self.class} #{to_s}>"
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
# Get the key-multiplicity pairs (even those with zero multiplicities).
|
197
|
+
#
|
198
|
+
# @return [Hash]
|
199
|
+
def entries
|
200
|
+
@entries ||= {}
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def SignedMultiset(input)
|
205
|
+
SignedMultiset.new(input)
|
206
|
+
end
|
data/signed_multiset.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'signed_multiset
|
4
|
+
require 'signed_multiset'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "signed_multiset"
|
@@ -9,17 +9,15 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Josh Lewis"]
|
10
10
|
spec.email = ["josh.w.lewis@gmail.com"]
|
11
11
|
spec.description = %q{Multisets with negative membership}
|
12
|
-
spec.summary = %q{
|
12
|
+
spec.summary = %q{You can think of it as a Multiset or Bag that allows for negative counts. It's functionality is very similar to Sorted Sets available in Redis (albeit without the storage functionality). It feels like a Ruby Hash or Array, but with some differences.}
|
13
13
|
spec.homepage = "http://github.com/joshwlewis/signed_multiset"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
21
|
spec.add_development_dependency "rake"
|
23
22
|
spec.add_development_dependency "minitest"
|
24
|
-
|
25
|
-
end
|
23
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'signed_multiset'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/pride'
|
2
5
|
|
3
6
|
describe SignedMultiset do
|
4
7
|
subject { SignedMultiset.new(foo: 4, bar: 2, baz: 0) }
|
@@ -20,11 +23,8 @@ describe SignedMultiset do
|
|
20
23
|
set = SignedMultiset.new(subject)
|
21
24
|
set.keys.must_equal([:foo, :bar])
|
22
25
|
end
|
23
|
-
|
24
|
-
|
25
|
-
describe "::[]" do
|
26
|
-
it "must create a new set" do
|
27
|
-
set = SignedMultiset[:a, :b, :b, :c]
|
26
|
+
it "must accept additional arguments" do
|
27
|
+
set = SignedMultiset.new(:a, :b, :c)
|
28
28
|
set.keys.must_equal([:a, :b, :c])
|
29
29
|
end
|
30
30
|
end
|
@@ -187,8 +187,8 @@ describe SignedMultiset do
|
|
187
187
|
end
|
188
188
|
|
189
189
|
describe "#<=>" do
|
190
|
-
let(:small) { SignedMultiset[:foo, :bar] }
|
191
|
-
let(:large) { SignedMultiset[:foo, :bar, :baz, :foo, :bar, :qux, :foo, :bar] }
|
190
|
+
let(:small) { SignedMultiset.new([:foo, :bar]) }
|
191
|
+
let(:large) { SignedMultiset.new([:foo, :bar, :baz, :foo, :bar, :qux, :foo, :bar]) }
|
192
192
|
let(:equal) { subject.dup }
|
193
193
|
|
194
194
|
it "should return 1 when compared to a smaller set" do
|
@@ -201,4 +201,11 @@ describe SignedMultiset do
|
|
201
201
|
(subject <=> equal).must_equal(0)
|
202
202
|
end
|
203
203
|
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "::SignedMultiset()" do
|
207
|
+
it "must create a new set" do
|
208
|
+
set = SignedMultiset([:a, :b, :b, :c])
|
209
|
+
set.keys.must_equal([:a, :b, :c])
|
210
|
+
end
|
204
211
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: signed_multiset
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Lewis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,11 +68,8 @@ files:
|
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
70
|
- lib/signed_multiset.rb
|
71
|
-
- lib/signed_multiset/signed_multiset.rb
|
72
|
-
- lib/signed_multiset/version.rb
|
73
71
|
- signed_multiset.gemspec
|
74
|
-
- test/
|
75
|
-
- test/test_helper.rb
|
72
|
+
- test/signed_multiset_test.rb
|
76
73
|
homepage: http://github.com/joshwlewis/signed_multiset
|
77
74
|
licenses:
|
78
75
|
- MIT
|
@@ -96,10 +93,9 @@ rubyforge_project:
|
|
96
93
|
rubygems_version: 2.0.2
|
97
94
|
signing_key:
|
98
95
|
specification_version: 4
|
99
|
-
summary:
|
100
|
-
|
101
|
-
It feels like a Ruby Hash or Array, but with some differences.
|
96
|
+
summary: You can think of it as a Multiset or Bag that allows for negative counts.
|
97
|
+
It's functionality is very similar to Sorted Sets available in Redis (albeit without
|
98
|
+
the storage functionality). It feels like a Ruby Hash or Array, but with some differences.
|
102
99
|
test_files:
|
103
|
-
- test/
|
104
|
-
- test/test_helper.rb
|
100
|
+
- test/signed_multiset_test.rb
|
105
101
|
has_rdoc:
|
@@ -1,206 +0,0 @@
|
|
1
|
-
class SignedMultiset
|
2
|
-
|
3
|
-
include Enumerable
|
4
|
-
include Comparable
|
5
|
-
|
6
|
-
# Create a new instance with a list of objects.
|
7
|
-
#
|
8
|
-
# @param *list [Object] A list of objects to add to the set
|
9
|
-
def self.[](*list)
|
10
|
-
new(list)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Create a new SignedMultiset instance.
|
14
|
-
#
|
15
|
-
# @param object [Enumerable, nil] An array of keys, or key-muliplicity pairs.
|
16
|
-
def initialize(object=nil)
|
17
|
-
if object.is_a?(Enumerable)
|
18
|
-
object.each { |k, v| increment(k, v || 1) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Get the non-zero key-multiplicity pairs.
|
23
|
-
#
|
24
|
-
# @return [Hash]
|
25
|
-
def multiplicities
|
26
|
-
entries.reject{|k,v| v == 0}
|
27
|
-
end
|
28
|
-
|
29
|
-
# Iterate over the multiplicity collection.
|
30
|
-
#
|
31
|
-
# @return [Enumerator]
|
32
|
-
def each(*args, &block)
|
33
|
-
if block_given?
|
34
|
-
multiplicities.each { |k,v| yield(k,v) }
|
35
|
-
else
|
36
|
-
multiplicities.each(args)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Get the multiplicity for a key.
|
41
|
-
#
|
42
|
-
# @param key [Object] The key to get the multiplicity of
|
43
|
-
# @return [Integer, nil] The multiplicity for the key, or nil if the key is
|
44
|
-
# not present, or has a zero multiplicity
|
45
|
-
def [](key)
|
46
|
-
multiplicities[key]
|
47
|
-
end
|
48
|
-
|
49
|
-
# Set the multiplicity for a key.
|
50
|
-
#
|
51
|
-
# @param key [Object] The key to set the multiplicity of
|
52
|
-
# @param multiplicity [Integer] The desired multiplicity
|
53
|
-
# @return [Integer] The multiplicity for the key
|
54
|
-
def []=(key, multiplicity)
|
55
|
-
entries[key] = multiplicity
|
56
|
-
self[key]
|
57
|
-
end
|
58
|
-
|
59
|
-
# Increment the multiplicity for a key.
|
60
|
-
#
|
61
|
-
# @param key (see #[]=)
|
62
|
-
# @param value [Integer] The desired increment value, positive or negative
|
63
|
-
# @return (see #[]=)
|
64
|
-
def increment(key, value)
|
65
|
-
entries[key] ||= 0
|
66
|
-
entries[key] += value
|
67
|
-
self[key]
|
68
|
-
end
|
69
|
-
|
70
|
-
# Increment multiplicity by 1 for a key. This method is chainable.
|
71
|
-
#
|
72
|
-
# @param key [Object] The key to increment the multiplicity of
|
73
|
-
# @return [self]
|
74
|
-
def <<(key)
|
75
|
-
increment(key, 1)
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
|
-
# Remove key completely from the set, similar to [key]=0
|
80
|
-
#
|
81
|
-
# @param key [Object] The key to remove
|
82
|
-
# @return [Integer] The multiplicity of the item removed.
|
83
|
-
def delete(key)
|
84
|
-
entries.delete(key)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Creates a new instance of equal to current instance
|
88
|
-
# @return [SignedMultiset]
|
89
|
-
def dup
|
90
|
-
self.class.new(multiplicities)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Combine self with another SignedMultiset via addition to create a merged instance.
|
94
|
-
#
|
95
|
-
# @param other [SignedMultiset]
|
96
|
-
# @return [SignedMultiset]
|
97
|
-
def +(other)
|
98
|
-
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
99
|
-
m.increment(k,v); m
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Combine self with another SignedMultiset via subtraction to create a merged instance.
|
104
|
-
#
|
105
|
-
# @param other (see #+)
|
106
|
-
# @return (see #+)
|
107
|
-
def -(other)
|
108
|
-
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
109
|
-
m.increment(k,-v); m
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# Combine self with another SignedMultiset via union to create a merged instance.
|
114
|
-
#
|
115
|
-
# @param other (see #+)
|
116
|
-
# @return (see #+)
|
117
|
-
def |(other)
|
118
|
-
(keys | other.keys).reduce(self.class.new) do |m, k|
|
119
|
-
m.increment(k, [self[k] || 0, other[k] || 0].max); m
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Combine self with another SignedMultiset via intersection to create a merged instance.
|
124
|
-
#
|
125
|
-
# @param other (see #+)
|
126
|
-
# @return (see #+)
|
127
|
-
def &(other)
|
128
|
-
(keys & other.keys).reduce(self.class.new) do |m, k|
|
129
|
-
m.increment(k, [self[k], other[k]].min); m
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Get the list of keys for self.
|
134
|
-
#
|
135
|
-
# @return [Array]
|
136
|
-
def keys
|
137
|
-
multiplicities.keys
|
138
|
-
end
|
139
|
-
|
140
|
-
# Get the multiplicity values for self.
|
141
|
-
#
|
142
|
-
# @return [Array]
|
143
|
-
def values
|
144
|
-
multiplicities.values
|
145
|
-
end
|
146
|
-
|
147
|
-
# Get the cardinality (sum of multiplicities) for self.
|
148
|
-
#
|
149
|
-
# @return [Integer]
|
150
|
-
def cardinality
|
151
|
-
values.inject(&:+)
|
152
|
-
end
|
153
|
-
alias_method :sum, :cardinality
|
154
|
-
|
155
|
-
# Get the count of unique keys in the SignedMultiset.
|
156
|
-
#
|
157
|
-
# @return [Integer]
|
158
|
-
def size
|
159
|
-
keys.size
|
160
|
-
end
|
161
|
-
alias_method :length, :size
|
162
|
-
|
163
|
-
# Compare self with another SignedMultiset
|
164
|
-
#
|
165
|
-
# @param other (see #+)
|
166
|
-
# @return [-1,0,1]
|
167
|
-
def <=>(other)
|
168
|
-
if [:multiplicities, :cardinality, :size].all? { |m| other.respond_to?(m) }
|
169
|
-
if multiplicities == other.multiplicities
|
170
|
-
0
|
171
|
-
elsif cardinality != other.cardinality
|
172
|
-
cardinality <=> other.cardinality
|
173
|
-
elsif size != other.size
|
174
|
-
size <=> other.size
|
175
|
-
else
|
176
|
-
multiplicities <=> other.multiplicities
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
def to_hash
|
182
|
-
multiplicities.dup
|
183
|
-
end
|
184
|
-
|
185
|
-
def to_a
|
186
|
-
multiplicities.to_a
|
187
|
-
end
|
188
|
-
|
189
|
-
def to_s
|
190
|
-
multiplicities.map{ |k,m| "#{k}: #{m}"}.join(', ')
|
191
|
-
end
|
192
|
-
|
193
|
-
def inspect
|
194
|
-
"<#{self.class} #{to_s}>"
|
195
|
-
end
|
196
|
-
|
197
|
-
private
|
198
|
-
|
199
|
-
# Get the key-multiplicity pairs (even those with zero multiplicities).
|
200
|
-
#
|
201
|
-
# @return [Hash]
|
202
|
-
def entries
|
203
|
-
@entries ||= {}
|
204
|
-
end
|
205
|
-
|
206
|
-
end
|
data/test/test_helper.rb
DELETED