Class: Range

Inherits:
Object show all
Includes:
Random::RangeExtensions
Defined in:
lib/core/facets/range/nudge.rb,
lib/core/facets/range/op_add.rb,
lib/core/facets/range/op_sub.rb,
lib/core/facets/range/to_rng.rb,
lib/core/facets/range/within.rb,
lib/core/facets/range/combine.rb,
lib/core/facets/range/overlap.rb,
lib/core/facets/range/quantile.rb,
lib/standard/facets/random.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Random::RangeExtensions

#at_rand

Class Method Details

.combine(*intervals) ⇒ Object

Combine intervals.

Range.combine(1..2, 2..4)   #=> [1..4]
Range.combine(1..2, 3..4)   #=> [1..2, 3..4]

CREDIT: Trans


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/core/facets/range/combine.rb', line 23

def self.combine(*intervals)
  intype = intervals.first.class
  result = []

  intervals = intervals.collect do |i|
    [i.first, i.last]
  end

  intervals.sort.each do |(from, to)|  #inject([]) do |result,
    if result.empty? or from > result.last[1]
      result << [from, to]
    elsif to > result.last[1]
      result.last[1] = to
    end
    #result
  end

  if intype <= Range
    result.collect{ |i| ((i.first)..(i.last)) }
  else
    result
  end
end

Instance Method Details

#+(value) ⇒ Object

Add two ranges to create a range array.

Returns [Array]

CREDIT: monocle


11
12
13
# File 'lib/core/facets/range/op_add.rb', line 11

def +(value)
	[self, value].arrange
end

#-(value) ⇒ Object

Subtract one range from another producing a range array.

Examples

(1..10) - (4..6)  => [1..3, 7..10]

(1..10) - (9..12) => [1..8]

Returns [Array]

CREDIT: monocle


15
16
17
18
19
20
21
# File 'lib/core/facets/range/op_sub.rb', line 15

def -(value)
	if value.class == first.class
		minus_obj(value)
	else
		[minus_obj(value.first)[0], minus_obj(value.last)[1]].compact
	end
end

#combine(*intervals) ⇒ Object

Combine ranges.

(1..2).combine(2..4)   #=> [1..4]
(1..2).combine(3..4)   #=> [1..2, 3..4]

TODO: Incorporate end-sentinal inclusion vs. exclusion.

CREDIT: Trans


12
13
14
# File 'lib/core/facets/range/combine.rb', line 12

def combine(*intervals)
  Range.combine(self, *intervals)
end

#minus_obj(value) ⇒ Object (private)

TODO: Better name? Maybe make public?


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/core/facets/range/op_sub.rb', line 26

def minus_obj(value)
 f = case value <=> first.succ
     when -1 then nil
    		when  0 then first
     	else
    		  #value < last.succ ? first...value : self
    		  value < last.succ ? first..(value.pred) : self
       end

 s = case last <=> value.succ
       when -1 then nil
       when  0 then last
       else
         value.succ > first ? (value.succ)..last : self
       end

 [f, s]
end

#nudge(value = 1, min: nil, max: nil) ⇒ Object

Nudge range values

(1..5).nudge           #=> 2..6
(1..5).nudge(2)        #=> 3..7
(1..5).nudge(-2)       #=> -1..3
(1..5).nudge(min: 1)   #=> 2..5
(1..5).nudge(max: 1)   #=> 1..6

CREDIT: Codeindulgence


13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/core/facets/range/nudge.rb', line 13

def nudge(value = 1, min: nil, max: nil)
  if min or max
    min ||= 0
    max ||= 0
  else
    min = max = value
  end
  
  if exclude_end?
    (self.min + min)...((self.max + 1) + max)
  else
    (self.min + min)..(self.max + max)
  end
end

#overlap?(other) ⇒ Boolean

Do two ranges overlap?

CREDIT: Daniel Schierbeck, Brandon Keepers

Returns:

  • (Boolean)

7
8
9
# File 'lib/core/facets/range/overlap.rb', line 7

def overlap?(other)
  include?(other.first) or other.include?(first)
end

#quantile(k, n = 100) ⇒ Integer

Calculate the kth n-tile in a range.

If n=4 the quantity is called a quartile, and if n=100 it is called a percentile.

Returns:

Uncommon:

  • require 'facets/range/quantile'


12
13
14
15
16
# File 'lib/core/facets/range/quantile.rb', line 12

def quantile(k, n=100)
  return 1 if k < first
  return n if k >= last
  ((k - first) / ((last - first) / n.to_f)).to_i + 1
end

#to_rangeObject

A thing really should know itself. This simply returns self.

Note: This does not internally effect the Ruby interpretor such that it can coerce Range-like objects into a Range.

CREDIT: Trans


21
22
23
# File 'lib/core/facets/range/to_rng.rb', line 21

def to_range
  self
end

#to_rngObject

A thing really should know itself. This simply returns self.

CREDIT: Trans


8
9
10
# File 'lib/core/facets/range/to_rng.rb', line 8

def to_rng
  self
end

#umbrella(r) ⇒ Object

Returns a two element array of the relationship between two Ranges.

Diagram …

  Relationship     Returns

self |-----------|
r    |-----------|    [0,0]

self |-----------|
r     |---------|     [-1,-1]

self  |---------|
r    |-----------|    [1,1]

self |-----------|
r     |----------|    [-1,0]

self |-----------|
r     |-----------|   [-1,1]

etc.

Example:

(0..3).umbrella(1..2)  #=>  [-1,-1]

CREDIT: Trans, Chris Kappler


49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/core/facets/range/within.rb', line 49

def umbrella(r)
  s = first <=> r.first
  e = r.last <=> last

  if e == 0
    if r.exclude_end? and exclude_end?
      e = r.max <=> max
    else
      e = (r.exclude_end? ? 0 : 1) <=> (exclude_end? ? 0 : 1)
    end
  end

  return s,e
end

#within?(rng) ⇒ Boolean

Uses the Range#umbrella method to determine if another Range is anywhere within this Range.

(1..3).within?(0..4)  #=> true

CREDIT: Trans

Returns:

  • (Boolean)

10
11
12
13
14
15
16
17
# File 'lib/core/facets/range/within.rb', line 10

def within?(rng)
  case rng.umbrella(self)
  when [0,0], [-1,0], [0,-1], [-1,-1]
    return true
  else
    return false
  end
end