Module: CoreExtensions::Range::Operations::ClassMethods

Defined in:
lib/core_extensions/range/operations.rb

Instance Method Summary collapse

Instance Method Details

#merge(*ranges) ⇒ Array<Range>

Merge the given ranges together.

Examples:

Merge two ranges.

Range.merge(1..5, 2..6) #=> [1..6]

Merge an endless range with a non-endless range.

Range.merge(1..5, 2..) #=> [1..]

Merge two endless ranges.

Range.merge(1.., 2..) #=> [1..]

Can’t merge an open range with a range whose start is the same as the open range’s end.

Range.merge(1...3, 3..5) #=> [1...3, 3..5]

Parameters:

  • ranges (Array<Range>)

    The ranges objects to merge.

Returns:

  • (Array<Range>)

    An array of potentially merged ranges.



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/core_extensions/range/operations.rb', line 74

def merge(*ranges)
  ranges.sort_by!(&:begin).inject([]) do |merged, range|
    if merged.empty? || !range.overlaps?(merged.last)
      merged.append(range)
    else
      last_range = merged.pop

      merged.append(merge_ranges(last_range, range))
    end
  end
end

#subtract(original_range, *subtracted_ranges, delta: 1) ⇒ Object

Subtract an array of ranges from the given original range.

Examples:

Subtraction of closed, finite ranges.

Range.subtract(1..20, 2..3, 4..6, 7..12) #=> [1...2, 13..20]

Subtraction of a mixture of closed and open finite ranges.

Range.subtract(1..20, 2..3, 4...6, 7..12) #=> [1...2, 6...7, 13..20]

Subtraction of finite ranges from an endless range

Range.subtract(1.., 2..3, 4...6, 7..12) #=> [1...2, 4...7, 13..]

Subtraction of two endless ranges

Range.subtract(1.., 10..) #=> [1...10]
Range.subtract(10.., 1..) #=> []

Parameters:

  • original_range (Range)

    The range to subtract from.

  • subtracted_ranges (Array<Range>)

    The ranges to subtract from ‘original_range`

  • delta (defaults to: 1)

    The amount which should be added to the begin of a resulting subrange in the event that the previous subrange end was open.



107
108
109
110
111
112
113
114
115
# File 'lib/core_extensions/range/operations.rb', line 107

def subtract(original_range, *subtracted_ranges, delta: 1)
  subtracted_ranges.sort_by!(&:begin).inject([original_range]) do |result, subtracted_range|
    if result.last&.overlaps?(subtracted_range)
      result.append(*subtract_overlapping_range(result.pop, subtracted_range, delta: delta))
    else
      result
    end
  end
end