Class: Multiset

Inherits:
Set
  • Object
show all
Defined in:
lib/rack/mount/vendor/multimap/multiset.rb

Overview

Multiset implements a collection of unordered values and allows duplicates.

Example

require 'multiset'
s1 = Multiset.new [1, 2]              # -> #<Multiset: {1, 2}>
s1.add(2)                             # -> #<Multiset: {1, 2, 2}>
s1.merge([2, 6])                      # -> #<Multiset: {1, 2, 2, 2, 3}>
s1.multiplicity(2)                    # -> 3
s1.multiplicity(3)                    # -> 1

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ Multiset

:nodoc:



15
16
17
18
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 15

def initialize(*args, &block) #:nodoc:
  @hash = Hash.new(0)
  super
end

Instance Method Details

#&(enum) ⇒ Object Also known as: intersection

Returns a new set containing elements common to the set and the given enumerable object.



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 129

def &(enum)
  s = dup
  n = self.class.new
  enum.each { |o|
    if s.include?(o)
      s.delete(o, 1)
      n.add(o)
    end
  }
  n
end

#^(enum) ⇒ Object

Returns a new set containing elements exclusive between the set and the given enumerable object. (set ^ enum) is equivalent to ((set | enum) - (set & enum)).



145
146
147
148
149
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 145

def ^(enum)
  n = self.class.new(enum)
  each { |o| n.include?(o) ? n.delete(o, 1) : n.add(o) }
  n
end

#add(o) ⇒ Object Also known as: <<

Adds the given object to the set and returns self. Use merge to add many elements at once.



80
81
82
83
84
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 80

def add(o)
  @hash[o] ||= 0
  @hash[o] += 1
  self
end

#cardinalityObject Also known as: size, length

Returns the total number of elements in a multiset, including repeated memberships



27
28
29
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 27

def cardinality
  @hash.inject(0) { |s, (e, m)| s += m }
end

#delete(o, n = nil) ⇒ Object

Deletes all the identical object from the set and returns self. If n is given, it will remove that amount of identical objects from the set. Use subtract to delete many different items at once.



93
94
95
96
97
98
99
100
101
102
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 93

def delete(o, n = nil)
  if n
    @hash[o] ||= 0
    @hash[o] -= n if @hash[o] > 0
    @hash.delete(o) if @hash[o] == 0
  else
    @hash.delete(o)
  end
  self
end

#delete_ifObject

Deletes every element of the set for which block evaluates to true, and returns self.



108
109
110
111
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 108

def delete_if
  each { |o| delete(o) if yield(o) }
  self
end

#eachObject

Calls the given block once for each element in the set, passing the element as parameter. Returns an enumerator if no block is given.



69
70
71
72
73
74
75
76
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 69

def each
  @hash.each_pair do |key, multiplicity|
    multiplicity.times do
      yield(key)
    end
  end
  self
end

#eql?(set) ⇒ Boolean Also known as: ==

Returns true if two sets are equal. Two multisets are equal if they have the same cardinalities and each element has the same multiplicity in both sets. The equality of each element inside the multiset is defined according to Object#eql?.

Returns:

  • (Boolean)


155
156
157
158
159
160
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 155

def eql?(set)
  return true if equal?(set)
  set = self.class.new(set) unless set.is_a?(self.class)
  return false unless cardinality == set.cardinality
  superset?(set) && subset?(set)
end

#marshal_dumpObject

:nodoc:



163
164
165
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 163

def marshal_dump #:nodoc:
  @hash
end

#marshal_load(hash) ⇒ Object

:nodoc:



167
168
169
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 167

def marshal_load(hash) #:nodoc:
  @hash = hash
end

#merge(enum) ⇒ Object

Merges the elements of the given enumerable object to the set and returns self.



115
116
117
118
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 115

def merge(enum)
  enum.each { |o| add(o) }
  self
end

#multiplicity(e) ⇒ Object

Returns the number of times an element belongs to the multiset.



21
22
23
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 21

def multiplicity(e)
  @hash[e]
end

#proper_subset?(set) ⇒ Boolean

Returns true if the set is a proper subset of the given set.

Returns:

  • (Boolean)


60
61
62
63
64
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 60

def proper_subset?(set)
  set.is_a?(self.class) or raise ArgumentError, "value must be a set"
  return false if set.cardinality <= cardinality
  all? { |o| multiplicity(o) <= set.multiplicity(o) }
end

#proper_superset?(set) ⇒ Boolean

Returns true if the set is a proper superset of the given set.

Returns:

  • (Boolean)


46
47
48
49
50
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 46

def proper_superset?(set)
  set.is_a?(self.class) or raise ArgumentError, "value must be a set"
  return false if cardinality <= set.cardinality
  set.all? { |o| set.multiplicity(o) <= multiplicity(o) }
end

#subset?(set) ⇒ Boolean

Returns true if the set is a subset of the given set.

Returns:

  • (Boolean)


53
54
55
56
57
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 53

def subset?(set)
  set.is_a?(self.class) or raise ArgumentError, "value must be a set"
  return false if set.cardinality < cardinality
  all? { |o| multiplicity(o) <= set.multiplicity(o) }
end

#subtract(enum) ⇒ Object

Deletes every element that appears in the given enumerable object and returns self.



122
123
124
125
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 122

def subtract(enum)
  enum.each { |o| delete(o, 1) }
  self
end

#superset?(set) ⇒ Boolean

Returns true if the set is a superset of the given set.

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 39

def superset?(set)
  set.is_a?(self.class) or raise ArgumentError, "value must be a set"
  return false if cardinality < set.cardinality
  set.all? { |o| set.multiplicity(o) <= multiplicity(o) }
end

#to_aObject

Converts the set to an array. The order of elements is uncertain.



34
35
36
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 34

def to_a
  inject([]) { |ary, (key, _)| ary << key }
end

#to_yaml(opts = {}) ⇒ Object

:nodoc:



171
172
173
174
175
176
177
178
179
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 171

def to_yaml(opts = {}) #:nodoc:
  YAML::quick_emit(self, opts) do |out|
    out.map(taguri, to_yaml_style) do |map|
      @hash.each do |k, v|
        map.add(k, v)
      end
    end
  end
end

#yaml_initialize(tag, val) ⇒ Object

:nodoc:



181
182
183
184
# File 'lib/rack/mount/vendor/multimap/multiset.rb', line 181

def yaml_initialize(tag, val) #:nodoc:
  @hash = val
  self
end