Sha256: 73b646cac5a0f7e70e690404515213c3cc9dcc281c589ce1729508c2d9ea52b4

Contents?: true

Size: 1.97 KB

Versions: 5

Compression:

Stored size: 1.97 KB

Contents

class String

  def distance_to(s)
    return nil if not String === s
    parts1 = split_parts
    parts2 = s.split_parts
    return nil if parts1.length != parts2.length
    s1 = ""
    s2 = ""
    parts1.length.times do |pos|
      return nil if parts1[pos].split_type != parts2[pos].split_type
      if parts1[pos].split_type == :other
        return nil if parts1[pos] != parts2[pos]
      else
        if s1.length != 0
          return nil if parts1[pos].length > parts2[pos].length
        else
          parts1[pos] = case parts1[pos].split_type
                        when :numeric
                          "0"
                        when :upper_case
                          "\100"
                        when :lower_case
                          "\140"
                        end * (parts2[pos].length - parts1[pos].length) + parts1[pos]
        end
        s1 << parts1[pos]
        s2 << parts2[pos]
      end
    end
    s2.split_value - s1.split_value
  end

  def <=>(s)
    d = distance_to(s)
    return nil if d.nil?
    return 1 if d < 0
    return -1 if d > 0
    0
  end

  def split_parts
    scan(/[0-9]+|[a-z]+|[A-Z]+|[^0-9a-zA-Z]+/)
  end

  def split_type
    case self
    when /[0-9]/
      :numeric
    when /[a-z]/
      :lower_case
    when /[A-Z]/
      :upper_case
    else
      :other
    end
  end

  def split_value
    result = 0
    each_byte do |b|
      case b
      when ?0..?9
        result = result * 10 + b - ?0
      when (?a-1)..?z
        result = result * 26 + b - ?a
      when (?A-1)..?Z
        result = result * 26 + b - ?A
      end
    end
    result
  end

  def succ(n=1)
    result = self.dup
    n.times {result.succ!}
    result
  end

end


# --- test ---

if $0 == __FILE__

  def try_it(a,b)
    puts "#{a.distance_to(b)}, #{a <=> b}"
  end
  
  a = "@#kF#9z4&&"
  b = a.succ(2000000)
  try_it(a,b)
  
  a = "a"
  b = "a"
  try_it(a,b)

  a = "a"
  b = "z"
  try_it(a,b)

  a = "A"
  b = "Z"
  try_it(a,b)

  a = "a"
  b = "Z"
  try_it(a,b)

end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
facets-0.6.3 lib/facet-dev/string/succ_distance.rb
facets-1.8.49 work/core/string/succ_distance.rb
facets-1.8.0 work/core/string/succ_distance.rb
facets-1.8.20 work/core/string/succ_distance.rb
facets-1.8.8 work/core/string/succ_distance.rb