Class: List

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/M500_containers.rb

Direct Known Subclasses

Set

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#to_list

Class Method Details

.[](*ary) ⇒ Object



37
38
39
# File 'lib/M500_containers.rb', line 37

def self.[](*ary)
  new(ary)
end

.new!(a = nil, &b) ⇒ Object



32
33
34
# File 'lib/M500_containers.rb', line 32

def List.new!(a=nil, &b)
  b ?  new(a) {b} : new(a)
end

Instance Method Details

#==(other) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
# File 'lib/M500_containers.rb', line 234

def ==(other)
  if self.equal?(other)
    true
  elsif other.instance_of?(self.class)
    @hash == other.instance_variable_get(:@hash)
  elsif other.is_a?(List) && self.size == other.size
    other.all? {|a| @hash.include?(a) }
  else
    false
  end
end

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



160
161
162
163
# File 'lib/M500_containers.rb', line 160

def add(a)
  @hash[a] = true
  self
end

#add?(a) ⇒ Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/M500_containers.rb', line 165

def add?(a)
 include?(a) ?      nil :      add(a)
end

#cartisian(a) ⇒ Object Also known as: *, x



252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/M500_containers.rb', line 252

def cartisian(a)
  # E.g.
  # {1, 2} × {red, white} = {(1, red), (1, white), (2, red), (2, white)}.
  # {1, 2, green} × {red, white, green} = {(1, red), (1, white), (1, green), (2, red), (2, white), (2, green), (green, red), (green, white), (green, green)}.
  # {1, 2} × {1, 2} = {(1, 1), (1, 2), (2, 1), (2, 2)}.
  #Some basic properties of cartesian products:
  #A × ∅ = ∅.
  #A × (B ∪ C) = (A × B) ∪ (A × C).
  #(A ∪ B) × C = (A × C) ∪ (B × C).
  #Let A and B be finite sets. Then
  #| A × B | = | B × A | = | A | × | B |.
end

#categorise_listObject Also known as: classify



266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/M500_containers.rb', line 266

def categorise_list
# e.g.:
#   files = List.new(Dir.glob("*.rb"))
#   ret = files.classify { |f| File.mtime(f).year }
#   p ret    # => {2010=>#<List: {"a.rb", "b.rb"}>,2011=>#<List: {"c.rb", "d.rb", "e.rb"}>,2012=>#<List: {"f.rb"}>}
  block_given? or return enum_for(__method__)
  h = {}
  each { |i|
    x = yield(i)
    (h[x] ||= self.class.new!).add(i)
  }
  h
end

#clearObject



85
86
87
88
# File 'lib/M500_containers.rb', line 85

def clear
  @hash.clear
  self
end

#collect!Object Also known as: map!



185
186
187
188
189
190
# File 'lib/M500_containers.rb', line 185

def collect!
  block_given? or return enum_for(__method__)
  li = self.class.new!
  each {|a| li << yield(a) }
  replace(li)
end

#contain_by_rule(&rule) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/M500_containers.rb', line 280

def contain_by_rule(&rule)
  rule or return enum_for(__method__)
  if rule.arity == 2
    require 'tsort'
    class << dig = {}         # :nodoc:
      include TSort
      alias tsort_each_node each_key
      def tsort_each_child(node, &block)
        fetch(node).each(&block)
      end
    end
    each { |u|
      dig[u] = a = []
      each{ |v| rule.call(u, v) and a << v }
    }
    li = List.new!()
    dig.each_strongly_connected_component { |css|
      li.add(self.class.new!(css))
    }
    li
  else
    List.new!(classify(&rule).values)
  end
  alias contain_by contain_by_rule
  alias divide contain_by_rule
end

#contianed_list?(li) ⇒ Boolean Also known as: subset?, <=

Returns:

  • (Boolean)


141
142
143
144
145
# File 'lib/M500_containers.rb', line 141

def contianed_list?(li)
  li.is_a?(List) or raise ArgumentError, "value must be a List"
  return false if li.size < size
  all? {|a| li.include?(a) }
end

#contianing_list?(li) ⇒ Boolean Also known as: superset?, >=

Returns:

  • (Boolean)


127
128
129
130
131
# File 'lib/M500_containers.rb', line 127

def contianing_list?(li)
  li.is_a?(List) or raise ArgumentError, "value must be a List"
  return false if size < li.size
  li.all? {|a| include?(a) }
end

#delete(a) ⇒ Object



168
169
170
171
# File 'lib/M500_containers.rb', line 168

def delete(a)
  @hash.delete(a)
  self
end

#delete?(a) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/M500_containers.rb', line 172

def delete?(a)
  include?(a) ?      delete(a) :      nil
end

#delete_ifObject



175
176
177
178
179
# File 'lib/M500_containers.rb', line 175

def delete_if
  block_given? or return enum_for(__method__)
  to_a.each {|a| @hash.delete(a) if yield(a) }
  self
end

#difference(a) ⇒ Object Also known as: -



217
218
219
# File 'lib/M500_containers.rb', line 217

def difference(a)
  dup.subtract(a)
end

#each(&block) ⇒ Object



155
156
157
158
159
# File 'lib/M500_containers.rb', line 155

def each(&block)
  block or return enum_for(__method__)
  @hash.each_key(&block)
  self
end

#empty?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/M500_containers.rb', line 82

def empty?
  @hash.empty?
end

#eql?(a) ⇒ Boolean

Returns:

  • (Boolean)


248
249
250
251
# File 'lib/M500_containers.rb', line 248

def eql?(a)
  return false unless a.is_a?(List)
  @hash.eql?(a.instance_variable_get(:@hash))
end

#flattenObject



117
118
119
# File 'lib/M500_containers.rb', line 117

def flatten
  self.class.new!.flatten_merge(self)
end

#flatten!Object



120
121
122
# File 'lib/M500_containers.rb', line 120

def flatten!
  detect {|e| e.is_a?(List) }?  replace(flatten()) : nil
end

#freezeObject



63
64
65
66
67
# File 'lib/M500_containers.rb', line 63

def freeze
  super
  @hash.freeze
  self
end

#hashObject



245
246
247
# File 'lib/M500_containers.rb', line 245

def hash
  @hash.hash
end

#initialize_copy(orig) ⇒ Object



60
61
62
# File 'lib/M500_containers.rb', line 60

def initialize_copy(orig)
  @hash = orig.instance_variable_get(:@hash).dup
end

#inspectObject



306
307
308
309
310
311
312
313
314
315
# File 'lib/M500_containers.rb', line 306

def inspect
  ids = (Thread.current[:__inspect_key__] ||= [])
  return sprintf('#<%s:: {...}>', self.class.name) if ids.include?(object_id)
  begin
    ids << object_id
    return sprintf('#<%s:: {%s}>', self.class, to_a.inspect[1..-2])
  ensure
    ids.pop
  end
end

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



221
222
223
224
225
# File 'lib/M500_containers.rb', line 221

def intersection(a)
  n = self.class.new!
  with_enum(a) {|b| n.add(b) if include?(b) }
  n
end

#keep_ifObject



180
181
182
183
184
# File 'lib/M500_containers.rb', line 180

def keep_if
  block_given? or return enum_for(__method__)
  to_a.each {|a| @hash.delete(a) unless yield(a) }
  self
end

#member?(a) ⇒ Boolean Also known as: include?

Returns:

  • (Boolean)


123
124
125
# File 'lib/M500_containers.rb', line 123

def member?(a)
  @hash.include?(a)
end

#merge(enum) ⇒ Object



204
205
206
207
# File 'lib/M500_containers.rb', line 204

def merge(enum)
  enum.instance_of?(self.class) ?  @hash.update(enum.instance_variable_get(:@hash)) :       with_enum(enum) { |o| add(o) }
  self
end

#pretty_print(pp) ⇒ Object Also known as: pp



316
317
318
319
320
321
322
323
324
# File 'lib/M500_containers.rb', line 316

def pretty_print(pp)
  pp.text sprintf('#<%s:: {', self.class.name)
  pp.nest(1) {
    pp.seplist(self) { |o|
      pp.pp o
    }
  }
  pp.text "}>"
end

#pretty_print_cycle(pp) ⇒ Object Also known as: pp_cycle



326
327
328
# File 'lib/M500_containers.rb', line 326

def pretty_print_cycle(pp)
  pp.text sprintf('#<%s:: {%s}>', self.class.name, empty? ? '' : '...')
end

#reject!(&block) ⇒ Object



192
193
194
195
196
197
# File 'lib/M500_containers.rb', line 192

def reject!(&block)
  block or return enum_for(__method__)
  n = size
  delete_if(&block)
  size == n ? nil : self
end

#replace(enum) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/M500_containers.rb', line 89

def replace(enum)
  if enum.instance_of?(self.class)
    @hash.replace(enum.instance_variable_get(:@hash))
  else
    clear
    merge(enum)
  end
  self
end

#select!(&block) ⇒ Object



198
199
200
201
202
203
# File 'lib/M500_containers.rb', line 198

def select!(&block)
  block or return enum_for(__method__)
  n = size
  keep_if(&block)
  size == n ? nil : self
end

#sizeObject Also known as: length



78
79
80
# File 'lib/M500_containers.rb', line 78

def size
  @hash.size
end

#strict_contianing_list?(li) ⇒ Boolean Also known as: proper_superset?, >

Returns:

  • (Boolean)


134
135
136
137
138
# File 'lib/M500_containers.rb', line 134

def strict_contianing_list?(li)
  li.is_a?(List) or raise ArgumentError, "value must be a List"
  return false if size <= li.size
  li.all? {|a| include?(a) }
end

#strictly_contianed_list?(li) ⇒ Boolean Also known as: proper_subset?, <

Returns:

  • (Boolean)


148
149
150
151
152
# File 'lib/M500_containers.rb', line 148

def strictly_contianed_list?(li)
  li.is_a?(List) or raise ArgumentError, "value must be a set"
  return false if li.size <= size
  all? {|a| li.include?(a) }
end

#subtract(enum) ⇒ Object



208
209
210
211
# File 'lib/M500_containers.rb', line 208

def subtract(enum)
  with_enum(enum) {|a| delete(a) }
  self
end

#symetric_difference(a) ⇒ Object Also known as: ^, sym_diff



227
228
229
230
231
# File 'lib/M500_containers.rb', line 227

def symetric_difference(a)
  n = List.new!(a)
  each {|b| if n.include?(b) then n.delete(b) else n.add(b) end }
  n
end

#taintObject



68
69
70
71
72
# File 'lib/M500_containers.rb', line 68

def taint
  super
  @hash.taint
  self
end

#to_aObject



98
99
100
# File 'lib/M500_containers.rb', line 98

def to_a
  @hash.keys
end

#union(a) ⇒ Object Also known as: +, |



212
213
214
# File 'lib/M500_containers.rb', line 212

def union(a)
  dup.merge(a)
end

#untaintObject



73
74
75
76
77
# File 'lib/M500_containers.rb', line 73

def untaint
  super
  @hash.untaint
  self
end