class List

Public Class Methods

[](*ary) click to toggle source
# File lib/M500_containers.rb, line 36
def self.[](*ary)
  new(ary)
end
new(a, &block) click to toggle source
# File lib/M500_containers.rb, line 39
def initialize(a, &block)
  @hash ||= Hash.new
  a.nil? and return
  if block
    with_enum(a) {|o| add(block[o]) }
  else
    merge(a)
  end
end
new!(a=nil, &b) click to toggle source
# File lib/M500_containers.rb, line 31
def List.new!(a=nil, &b)
  b ?  new(a) {b} : new(a)
end

Public Instance Methods

&(a)
Alias for: intersection
*(a)
Alias for: cartisian
+(a)
Alias for: union
-(a)
Alias for: difference
<(li)
<<(a)
Alias for: add
<=(li)
Alias for: contianed_list?
==(other) click to toggle source
# File lib/M500_containers.rb, line 233
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
>(li)
>=(li)
Alias for: contianing_list?
^(a)
Alias for: symetric_difference
add(a) click to toggle source
# File lib/M500_containers.rb, line 159
def add(a)
  @hash[a] = true
  self
end
Also aliased as: <<
add?(a) click to toggle source
# File lib/M500_containers.rb, line 164
def add?(a)
 include?(a) ?      nil :      add(a)
end
cartisian(a) click to toggle source
# File lib/M500_containers.rb, line 251
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
Also aliased as: *, x
categorise_list() { |i| ... } click to toggle source
# File lib/M500_containers.rb, line 265
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
Also aliased as: classify
classify()
Alias for: categorise_list
clear() click to toggle source
# File lib/M500_containers.rb, line 84
def clear
  @hash.clear
  self
end
collect!() { |a| ... } click to toggle source
# File lib/M500_containers.rb, line 184
def collect!
  block_given? or return enum_for(__method__)
  li = self.class.new!
  each {|a| li << yield(a) }
  replace(li)
end
Also aliased as: map!
contain_by_rule(&rule) click to toggle source
# File lib/M500_containers.rb, line 279
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) click to toggle source
# File lib/M500_containers.rb, line 140
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
Also aliased as: subset?, <=
contianing_list?(li) click to toggle source
# File lib/M500_containers.rb, line 126
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
Also aliased as: superset?, >=
delete(a) click to toggle source
# File lib/M500_containers.rb, line 167
def delete(a)
  @hash.delete(a)
  self
end
delete?(a) click to toggle source
# File lib/M500_containers.rb, line 171
def delete?(a)
  include?(a) ?      delete(a) :      nil
end
delete_if() { |a| ... } click to toggle source
# File lib/M500_containers.rb, line 174
def delete_if
  block_given? or return enum_for(__method__)
  to_a.each {|a| @hash.delete(a) if yield(a) }
  self
end
difference(a) click to toggle source
# File lib/M500_containers.rb, line 216
def difference(a)
  dup.subtract(a)
end
Also aliased as: -
each(&block) click to toggle source
# File lib/M500_containers.rb, line 154
def each(&block)
  block or return enum_for(__method__)
  @hash.each_key(&block)
  self
end
empty?() click to toggle source
# File lib/M500_containers.rb, line 81
def empty?
  @hash.empty?
end
eql?(a) click to toggle source
# File lib/M500_containers.rb, line 247
def eql?(a)
  return false unless a.is_a?(List)
  @hash.eql?(a.instance_variable_get(:@hash))
end
flatten() click to toggle source
# File lib/M500_containers.rb, line 116
def flatten
  self.class.new!.flatten_merge(self)
end
flatten!() click to toggle source
# File lib/M500_containers.rb, line 119
def flatten!
  detect {|e| e.is_a?(List) }?  replace(flatten()) : nil
end
freeze() click to toggle source
Calls superclass method
# File lib/M500_containers.rb, line 62
def freeze
  super
  @hash.freeze
  self
end
hash() click to toggle source
# File lib/M500_containers.rb, line 244
def hash
  @hash.hash
end
include?(a)
Alias for: member?
initialize_copy(orig) click to toggle source
# File lib/M500_containers.rb, line 59
def initialize_copy(orig)
  @hash = orig.instance_variable_get(:@hash).dup
end
inspect() click to toggle source
# File lib/M500_containers.rb, line 305
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) click to toggle source
# File lib/M500_containers.rb, line 220
def intersection(a)
  n = self.class.new!
  with_enum(a) {|b| n.add(b) if include?(b) }
  n
end
Also aliased as: &
keep_if() { |a| ... } click to toggle source
# File lib/M500_containers.rb, line 179
def keep_if
  block_given? or return enum_for(__method__)
  to_a.each {|a| @hash.delete(a) unless yield(a) }
  self
end
length()
Alias for: size
map!()
Alias for: collect!
member?(a) click to toggle source
# File lib/M500_containers.rb, line 122
def member?(a)
  @hash.include?(a)
end
Also aliased as: include?
merge(enum) click to toggle source
# File lib/M500_containers.rb, line 203
def merge(enum)
  enum.instance_of?(self.class) ?  @hash.update(enum.instance_variable_get(:@hash)) :       with_enum(enum) { |o| add(o) }
  self
end
pp(pp)
Alias for: pretty_print
pp_cycle(pp)
Alias for: pretty_print_cycle
pretty_print(pp) click to toggle source
# File lib/M500_containers.rb, line 315
def pretty_print(pp)
  pp.text sprintf('#<%s:: {', self.class.name)
  pp.nest(1) {
    pp.seplist(self) { |o|
      pp.pp o
    }
  }
  pp.text "}>"
end
Also aliased as: pp
pretty_print_cycle(pp) click to toggle source
# File lib/M500_containers.rb, line 325
def pretty_print_cycle(pp)
  pp.text sprintf('#<%s:: {%s}>', self.class.name, empty? ? '' : '...')
end
Also aliased as: pp_cycle
proper_subset?(li)
proper_superset?(li)
reject!(&block) click to toggle source
# File lib/M500_containers.rb, line 191
def reject!(&block)
  block or return enum_for(__method__)
  n = size
  delete_if(&block)
  size == n ? nil : self
end
replace(enum) click to toggle source
# File lib/M500_containers.rb, line 88
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) click to toggle source
# File lib/M500_containers.rb, line 197
def select!(&block)
  block or return enum_for(__method__)
  n = size
  keep_if(&block)
  size == n ? nil : self
end
size() click to toggle source
# File lib/M500_containers.rb, line 77
def size
  @hash.size
end
Also aliased as: length
strict_contianing_list?(li) click to toggle source
# File lib/M500_containers.rb, line 133
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
Also aliased as: proper_superset?, >
strictly_contianed_list?(li) click to toggle source
# File lib/M500_containers.rb, line 147
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
Also aliased as: proper_subset?, <
subset?(li)
Alias for: contianed_list?
subtract(enum) click to toggle source
# File lib/M500_containers.rb, line 207
def subtract(enum)
  with_enum(enum) {|a| delete(a) }
  self
end
superset?(li)
Alias for: contianing_list?
sym_diff(a)
Alias for: symetric_difference
symetric_difference(a) click to toggle source
# File lib/M500_containers.rb, line 226
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
Also aliased as: ^, sym_diff
taint() click to toggle source
Calls superclass method
# File lib/M500_containers.rb, line 67
def taint
  super
  @hash.taint
  self
end
to_a() click to toggle source
# File lib/M500_containers.rb, line 97
def to_a
  @hash.keys
end
union(a) click to toggle source
# File lib/M500_containers.rb, line 211
def union(a)
  dup.merge(a)
end
Also aliased as: +, |
untaint() click to toggle source
Calls superclass method
# File lib/M500_containers.rb, line 72
def untaint
  super
  @hash.untaint
  self
end
x(a)
Alias for: cartisian
|(a)
Alias for: union

Protected Instance Methods

flatten_merge(set, seen = List.new!) click to toggle source
# File lib/M500_containers.rb, line 100
def flatten_merge(set, seen = List.new!)
  set.each { |e|
    if e.is_a?(List)
      if seen.include?(e_id = e.object_id)
        raise ArgumentError, "tried to flatten recursive List"
      end
      seen.add(e_id)
      flatten_merge(e, seen)
      seen.delete(e_id)
    else
      add(e)
    end
  }
  self
end

Private Instance Methods

with_enum(enum, &block) click to toggle source
# File lib/M500_containers.rb, line 49
def with_enum(enum, &block)
  if enum.respond_to?(:each_entry)
    enum.each_entry(&block)
  elsif enum.respond_to?(:each)
    enum.each(&block)
  else
    raise ArgumentError, "value must be enumerable"
  end
end