Created
August 21, 2008 14:02
-
-
Save JosephPecoraro/6563 to your computer and use it in GitHub Desktop.
Strip similarities at the start and end of two strings. [ruby]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Strip Similarities between two strings | |
module Kernel | |
# | |
# strip_similiar | |
# Strips the similiarities at the start and end of each | |
# of the given strings, returning a list of both of the | |
# stripped strings. | |
# | |
# Example: | |
# strip_similiar( 'Ask Me Again', 'Ask You Again' ) #=> ['Me', 'You'] | |
# strip_similiar( 'blah', 'blah' ) #=> [nil, nil] | |
# strip_similiar( 'foo', 'bar' ) #=> ['foo', 'bar'] | |
# | |
def strip_similiar(left, right) | |
newLeft, newRight = strip_similiar_left(left, right) | |
strip_similiar_right( newLeft, newRight ) | |
end | |
# Strip from the front | |
def strip_similiar_left(left, right) | |
return [left,right] if left.nil? or right.nil? | |
ceil = [left.length, right.length].min | |
pos = 0 | |
pos.upto(ceil) do |i| | |
if left[i] == right[i] | |
pos += 1 | |
else | |
break | |
end | |
end | |
pos -= 1 if pos > ceil | |
return [ left[pos, left.length], right[pos, right.length] ] | |
end | |
# Strip from the back | |
def strip_similiar_right(left, right) | |
return [left,right] if left.nil? or right.nil? | |
floor = [left.length, right.length].min | |
pos = -1 | |
pos.downto(0-floor) do |i| | |
if left[i] == right[i] | |
pos -= 1 | |
else | |
break | |
end | |
end | |
return [ left[0..pos], right[0..pos] ] | |
end | |
end | |
# Test Cases | |
require 'test/unit' | |
class StripTest < Test::Unit::TestCase | |
def test_left | |
assert_equal( strip_similiar_left(' xa', ' xb') , ['a','b'] ) | |
assert_equal( strip_similiar_left('xxxa', 'xbbb'), ['xxa', 'bbb'] ) | |
assert_equal( strip_similiar_left('a','a') , ['', ''] ) | |
assert_equal( strip_similiar_left('This is a long test', 'This is a longer test'), [' test', 'er test'] ) | |
end | |
def test_right | |
assert_equal( strip_similiar_right('ax ', 'bx ') , ['a','b'] ) | |
assert_equal( strip_similiar_right('axxx', 'bbbx'), ['axx', 'bbb'] ) | |
assert_equal( strip_similiar_right('a','a') , ['', ''] ) | |
assert_equal( strip_similiar_right('This is a long test', 'This is a longer test'), ['This is a long', 'This is a longer'] ) | |
end | |
def test_both | |
assert_equal( strip_similiar(' xa', ' xb') , ['a','b'] ) # Left | |
assert_equal( strip_similiar('xxxa', 'xbbb'), ['xxa', 'bbb'] ) # Left | |
assert_equal( strip_similiar('ax ', 'bx ') , ['a','b'] ) # Right | |
assert_equal( strip_similiar('axxx', 'bbbx'), ['axx', 'bbb'] ) # Right | |
assert_equal( strip_similiar('a','a') , ['', ''] ) # Empty | |
assert_equal( strip_similiar(' ', ' ') , [' ', ''] ) # Not exactly empty | |
assert_equal( strip_similiar('blah', 'blah'), ['', ''] ) # Code Example | |
assert_equal( strip_similiar('foo', 'bar') , ['foo', 'bar'] ) # Code Example | |
assert_equal( strip_similiar( 'Ask Me Again', 'Ask You Again' ), ['Me', 'You'] ) # Code Example | |
assert_equal( strip_similiar('This is a long test', 'This is a longer test'), ['', 'er'] ) # Longer | |
end | |
end | |
# | |
# Sadly this doesn't work for multi-byte encodings (Unicode, UTF-8, ...) | |
# Anyone care to implement that? | |
# | |
# I guess you should get each character, then compare chars, instead of comparing | |
# characters by the str[#] method that I am. | |
# | |
# I think its much easier in Ruby 1.9, so I'll hold off a little longer | |
# | |
# Example Test case for multibyte chars: | |
# é => 195, 169 | |
# 195.chr.to_s => "\303" | |
# assert_equal( strip_similiar_left('é', 195.chr.to_s), ['é', "\303"] ) #=> FAILS | |
# | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment