Method: ElasticGraph::Support::TimeSet#intersection

Defined in:
lib/elastic_graph/support/time_set.rb

#intersection(other_set) ⇒ Object

Returns a new ‘TimeSet` containing `::Time`s common to this set and `other_set`.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/elastic_graph/support/time_set.rb', line 67

def intersection(other_set)
  # Here we rely on the distributive and commutative properties of set algebra:
  #
  # https://en.wikipedia.org/wiki/Algebra_of_sets
  # A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C) (distributive property)
  #       A ∩ B = B ∩ A             (commutative property)
  #
  # We can combine these properties to see how the intersection of sets of ranges would work:
  #          (A₁ ∪ A₂)        ∩        (B₁ ∪ B₂)
  # =        ((A₁ ∪ A₂) ∩ B₁) ∪ ((A₁ ∪ A₂) ∩ B₂)        (expanding based on distributive property)
  # =        (B₁ ∩ (A₁ ∪ A₂)) ∪ (B₂ ∩ (A₁ ∪ A₂))        (rearranging based on commutative property)
  # = ((B₁ ∩ A₁) ∪ (B₁ ∩ A₂)) ∪ ((B₂ ∩ A₁) ∪ (B₂ ∩ A₂)) (expanding based on distributive property)
  # =  (B₁ ∩ A₁) ∪ (B₁ ∩ A₂)  ∪  (B₂ ∩ A₁) ∪ (B₂ ∩ A₂)  (removing excess parens)
  # = union of (intersection of each pair)
  intersected_ranges = ranges.to_a.product(other_set.ranges.to_a)
    .filter_map { |r1, r2| intersect_ranges(r1, r2) }

  TimeSet.of_range_objects(intersected_ranges)
end