Class: RelationalMethods

Inherits:
Object
  • Object
show all
Defined in:
lib/joinable_array.rb

Class Method Summary collapse

Class Method Details

.fill_cube(left, right, &block) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/joinable_array.rb', line 26

def self.fill_cube(left, right, &block)
  right_hash = right[idx = 0]
  new_array = left.slice(0, 0)
  previously_added = nil
  left.each do |left_hash|
    while right_hash && (right_hash[:key] <=> left_hash[:key]) < 0
      if previously_added == nil || (right_hash[:key] <=> previously_added) > 0
        previously_added = right_hash[:key] 
        new_array << {:key => right_hash[:key], :object => block ? block.call(right_hash[:key]) : nil}
      end
      right_hash = right[idx += 1]
    end
    new_array << left_hash
    while right_hash && right_hash[:key] == left_hash[:key]
      right_hash = right[idx += 1]
    end
  end
  while right_hash
    if previously_added == nil || (right_hash[:key] <=> previously_added) > 0
      previously_added = right_hash[:key]
      new_array << {:key => right_hash[:key], :object => block ? block.call(right_hash[:key]) : nil}
    end
    right_hash = right[idx += 1]
  end
  new_array
end

.inner_join(left_a, right_a, left_key, right_key, &block) ⇒ Object



2
3
4
5
# File 'lib/joinable_array.rb', line 2

def self.inner_join(left_a, right_a, left_key, right_key, &block)
  left, right = left_and_right(left_a, right_a, left_key, right_key)
  join(left, right, left_a, &block)
end

.join(left, right, prototype_container) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/joinable_array.rb', line 53

def self.join(left, right, prototype_container)
  anchor = 0
  new_array = prototype_container.slice(0,0)
  left.each do |left_hash|
    right_hash = right[anchor]
    while right_hash && (right_hash[:key] <=> left_hash[:key]) < 0
      right_hash = right[anchor += 1]
    end
    idx = anchor
    while right_hash && right_hash[:key] == left_hash[:key]
      new_array << yield(left_hash[:object], right_hash[:object])
      right_hash = right[idx += 1]
    end
  end
  new_array
end

.left_and_right(left_a, right_a, left_key, right_key) ⇒ Object



70
71
72
73
74
# File 'lib/joinable_array.rb', line 70

def self.left_and_right(left_a, right_a, left_key, right_key)
  left = left_a.map {|x| {:key => left_key ? left_key.call(x) : 0, :object => x}}.sort_by {|x| x[:key]}
  right = right_a.map {|x| {:key => right_key ? right_key.call(x) : 0, :object => x}}.sort_by {|x| x[:key]}
  [left, right]
end

.left_join(left_a, right_a, left_key, right_key, fill, &block) ⇒ Object



7
8
9
10
11
# File 'lib/joinable_array.rb', line 7

def self.left_join(left_a, right_a, left_key, right_key, fill, &block)
  left, right = left_and_right(left_a, right_a, left_key, right_key)
  right = fill_cube(right, left, &fill).sort_by {|x| x[:key]}
  join(left, right, left_a, &block)
end

.outer_join(left_a, right_a, left_key, right_key, left_fill, right_fill, &block) ⇒ Object



19
20
21
22
23
24
# File 'lib/joinable_array.rb', line 19

def self.outer_join(left_a, right_a, left_key, right_key, left_fill, right_fill, &block)
  left, right = left_and_right(left_a, right_a, left_key, right_key)
  left = fill_cube(left, right, &left_fill).sort_by {|x| x[:key]}
  right = fill_cube(right, left, &right_fill).sort_by {|x| x[:key]}
  join(left, right, left_a, &block)
end

.right_join(left_a, right_a, left_key, right_key, fill, &block) ⇒ Object



13
14
15
16
17
# File 'lib/joinable_array.rb', line 13

def self.right_join(left_a, right_a, left_key, right_key, fill, &block)
  left, right = left_and_right(left_a, right_a, left_key, right_key)
  left = fill_cube(left, right, &fill).sort_by {|x| x[:key]}
  join(left, right, left_a, &block)
end