Class: UniPropUtils::RangeProcessor

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

Class Method Summary collapse

Class Method Details

.array_to_ranges(array) ⇒ Array<Range<Integer>>

Parameters:

  • array (Array<Integer>)

Returns:

  • (Array<Range<Integer>>)


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/uniprop/utils.rb', line 401

def array_to_ranges(array)
  array = array.uniq.sort << Float::INFINITY

  ranges = []

  pre_elm = nil
  begin_elm = nil

  array.each do |elm|
    if !pre_elm
      pre_elm = elm
      begin_elm = elm
    elsif elm != pre_elm+1
      ranges << Range.new(begin_elm, pre_elm)
      begin_elm = elm
    end
    pre_elm = elm
  end
  ranges
end

.cut_external(range, lower_limit, upper_limit) ⇒ Range<Integer>?

Note:

残す範囲にlower_limit, upper_limitも含まれる

rangeを最小がlower_limit、最大がupper_limitの範囲内で切って返す(範囲の外部を切る)。切った結果、範囲が残らない場合、nilを返す

Parameters:

  • range (Range<Integer>?)
  • lower_limit (Integer)
  • upper_limit (Integer)

Returns:

  • (Range<Integer>?)


473
474
475
476
477
478
479
# File 'lib/uniprop/utils.rb', line 473

def cut_external(range, lower_limit, upper_limit)
  return nil if range.max<lower_limit || upper_limit<range.min

  result_min = (range.min<lower_limit) ? lower_limit : range.min
  result_max = (upper_limit<range.max) ? upper_limit : range.max
  result_min..result_max
end

.cut_internal(range, lower_limit, upper_limit) ⇒ Range<Integer>?

Note:

残す範囲にlower_limit, upper_limitは含まれない

rangeを最小がlower_limit、最大がupper_limitの範囲内になるよう切って返す(範囲の内部を切る)。切った結果、範囲が残らない場合、nilを返す

Parameters:

  • range (Array<Range<Integer>>)
  • lower_limit (Integer)
  • upper_limit (Integer)

Returns:

  • (Range<Integer>?)


487
488
489
490
491
492
493
494
495
496
497
498
499
500
# File 'lib/uniprop/utils.rb', line 487

def cut_internal(range, lower_limit, upper_limit)
  inner_range =  cut_external((lower_limit..upper_limit), range.min, range.max)
  return [range] if !inner_range

  result = []
  if range.min < inner_range.min
    result << (range.min .. (inner_range.min-1))
  end
  if inner_range.max < range.max
    result << ((inner_range.max+1) .. range.max)
  end

  result
end

.intersection(range_array) ⇒ Object



422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/uniprop/utils.rb', line 422

def intersection(range_array)
  if range_array.size==0
    return nil
  else
    common_set = range_array[0].to_set
  end

  range_array.each do |range|
    common_set &= range.to_set
  end

  array_to_ranges(common_set.to_a)[0]
end

.intersections_between_range_arrays(*range_arrays) ⇒ Object



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# File 'lib/uniprop/utils.rb', line 436

def intersections_between_range_arrays(*range_arrays)
  common_set_of_range_arrays = nil

  range_arrays.each do |range_array|
    set_of_range_array = Set.new
    range_array.each { set_of_range_array.merge(_1.to_set) }
    
    if common_set_of_range_arrays
      common_set_of_range_arrays &= set_of_range_array
    else
      common_set_of_range_arrays = set_of_range_array
    end
  end

  array_to_ranges(common_set_of_range_arrays.to_a)
end

.max(array) ⇒ Integer?

array内のRangeのいずれかに含まれるIntegerのうち、最大のものを取得

Parameters:

  • array (Array<Range<Integer>>)

Returns:

  • (Integer?)

    arrayが空の場合nil



463
464
465
# File 'lib/uniprop/utils.rb', line 463

def max(array)
  array.max_by { _1.max }&.max
end

.min(array) ⇒ Integer?

array内のRangeのいずれかに含まれるIntegerのうち、最小のものを取得

Parameters:

  • array (Array<Range<Integer>>)

Returns:

  • (Integer?)

    arrayが空の場合nil



456
457
458
# File 'lib/uniprop/utils.rb', line 456

def min(array)
  array.min_by { _1.min }&.min
end

.str_to_range(str) ⇒ Range<Integer>

Note:

strはRange<Integer>を表している必要がある

a..b形式のstrをRange<Integer>に変換

Parameters:

  • str (String)

Returns:

  • (Range<Integer>)

Raises:

  • (ConvertError)

    strがRange<Integer>を表していない場合発生



507
508
509
510
511
512
513
514
# File 'lib/uniprop/utils.rb', line 507

def str_to_range(str)
  m = str.match(/^(\d+)\.\.(\d+)$/)
  if m
    return Range.new(m[1].to_i, m[2].to_i)
  else
    raise ConvertError, "Argument must be parsed as Range of Integer"
  end
end

.sub(range_array1, range_array2) ⇒ Object



388
389
390
391
392
393
394
395
396
397
# File 'lib/uniprop/utils.rb', line 388

def sub(range_array1, range_array2)
  range_array1 = sum_up(range_array1)
  range_array2 = sum_up(range_array2)

  array1 = (range_array1.map { _1.to_a }).flatten
  array2 = (range_array2.map { _1.to_a }).flatten

  non_dup_array = (Set.new(array1) - Set.new(array2)).to_a
  array_to_ranges(non_dup_array)
end

.sum_up(ranges) ⇒ Array<Range>

rangesに含まれるRangeオブジェクトを結合した結果を含むArrayを取得

Parameters:

  • ranges (Array<Range>)

Returns:

  • (Array<Range>)


375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/uniprop/utils.rb', line 375

def sum_up(ranges)
  scattered_ranges = []
  ranges.each do |range|
    if range.class==Range
      scattered_ranges << range.to_a
    elsif range.class==Integer
      scattered_ranges << range
    end
  end
  
  array_to_ranges(scattered_ranges.flatten)
end