Class: XRange

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/rmtools/enumerable/range.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#+, #dump, #export, #foldl, #foldr, #import, #map_hash, #present, #rand, #randsample, #recursive_find, #recursive_select, #threadify, #to_traversable, #urlencode, #xprod

Constructor Details

#initialize(*args) ⇒ XRange

Returns a new instance of XRange.



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/rmtools/enumerable/range.rb', line 238

def initialize *args
  if (str = args[0]).is String
    str.scan(/([&|v\^])?((-?\d+)\.\.(\.)?(-?\d+))/).each {|s|
      s[2], s[4] = s[2].to_i, s[4].to_i
      r = s[3] ? s[2]..s[4]-1 : s[2]..s[4]
      @ranges = case s[0]
                        when '&', '^'; intersect r
                        when '|', 'v'; union r
                        else [r]
                      end
    }
    @ranges.sort!
  else
    0.upto(args.sort!.size-2) {|i| args[i,2] = [nil, args[i]|args[i+1]] if args[i].x? args[i+1]}
    @ranges = args.compact.include_ends
  end
end

Instance Attribute Details

#rangesObject

Returns the value of attribute ranges.



235
236
237
# File 'lib/rmtools/enumerable/range.rb', line 235

def ranges
  @ranges
end

Instance Method Details

#&(range) ⇒ Object



256
257
258
259
260
261
262
# File 'lib/rmtools/enumerable/range.rb', line 256

def &(range)
  if range.is Range
    XRange.new *intersect(range)
  else
    @ranges.map {|r| range & r}.foldl(:|) || XRange.new
  end
end

#-(range) ⇒ Object



277
278
279
# File 'lib/rmtools/enumerable/range.rb', line 277

def -(range)
  self & -range
end

#-@Object



273
274
275
# File 'lib/rmtools/enumerable/range.rb', line 273

def -@
  @ranges.map {|r| -r}.foldl(:&) || XRange.new(-Inf..+Inf)
end

#^(range) ⇒ Object



281
282
283
284
# File 'lib/rmtools/enumerable/range.rb', line 281

def ^(range)
  common = self & range
  self - common | range - common
end

#bObject



322
323
324
# File 'lib/rmtools/enumerable/range.rb', line 322

def b
  !@ranges.empty? && self
end

#beginObject



330
331
332
# File 'lib/rmtools/enumerable/range.rb', line 330

def begin
  @begin ||= @ranges.first && @ranges.first.begin
end

#div(n) ⇒ Object



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/rmtools/enumerable/range.rb', line 347

def div(n)
  unless n < 1
    i = 0
    rarray = []
    j = @ranges[0].begin
    while range = @ranges[i]
      if j+n > range.end
        rarray << (j..range.end)
        i += 1
        j = @ranges[i].begin if @ranges[i]
      else
        rarray << (j..(j+=n)-1)
      end
    end
    rarray
  end
end

#each(&b) ⇒ Object



305
306
307
# File 'lib/rmtools/enumerable/range.rb', line 305

def each(&b) 
  @ranges.each {|r| r.each &b} 
end

#empty?Boolean

XRange doesn’t support ranges with end excluded, so it’s empty only if contains nothing

Returns:

  • (Boolean)


318
319
320
# File 'lib/rmtools/enumerable/range.rb', line 318

def empty?
  @ranges.empty?
end

#endObject



334
335
336
# File 'lib/rmtools/enumerable/range.rb', line 334

def end
  @end ||= @ranges.last && @ranges.last.end
end

#first(count = nil) ⇒ Object



339
340
341
# File 'lib/rmtools/enumerable/range.rb', line 339

def first(count=nil)
  count ? to_a_first(count) : self.begin
end

#include?(number_or_range) ⇒ Boolean

Returns:

  • (Boolean)


326
327
328
# File 'lib/rmtools/enumerable/range.rb', line 326

def include?(number_or_range)
  @ranges.find_include?(number_or_range)
end

#inspectObject



365
366
367
# File 'lib/rmtools/enumerable/range.rb', line 365

def inspect
  "XRange(#{@ranges.join(', ').gsub('-Infinity', '-∞').gsub('Infinity', '+∞')})"
end

#last(count = nil) ⇒ Object



343
344
345
# File 'lib/rmtools/enumerable/range.rb', line 343

def last(count=nil)
  count ? to_a.last(count) : self.end
end

#of(ary) ⇒ Object



309
310
311
# File 'lib/rmtools/enumerable/range.rb', line 309

def of(ary) 
  @ranges.sum_of(ary)
end

#sizeObject



313
314
315
# File 'lib/rmtools/enumerable/range.rb', line 313

def size
  @size ||= @ranges.sum_size
end

#to_a_firstObject



338
# File 'lib/rmtools/enumerable/range.rb', line 338

alias :to_a_first :first

#x?(range) ⇒ Boolean Also known as: intersects?

Returns:

  • (Boolean)


286
287
288
# File 'lib/rmtools/enumerable/range.rb', line 286

def x?(range)
  @ranges.any? {|r| range.x? r}
end

#|(range) ⇒ Object



264
265
266
267
268
269
270
271
# File 'lib/rmtools/enumerable/range.rb', line 264

def |(range)
  if range.is Range
    XRange.new *union(range)
  else
    @ranges.each {|r| range |= r}
    range
  end
end