Skip to content

Instantly share code, notes, and snippets.

@mamantoha
Created October 16, 2012 11:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mamantoha/3898678 to your computer and use it in GitHub Desktop.
Save mamantoha/3898678 to your computer and use it in GitHub Desktop.
Finding the longest common prefix of an array of paths in Ruby
# Return the longest path prefix (taken character-by-character) that is a prefix of all paths in array.
# If array is empty, return the empty string ('').
# Note that this may return invalid paths because it works a character at a time.
#
def common_prefix(m)
# Given a array of pathnames, returns the longest common leading component
return '' if m.empty?
s1, s2 = m.min, m.max
s1.each_char.with_index do |c, i|
return s1[0...i] if c != s2[i]
end
return s1
end
# Return the longest path prefix that is a prefix of all paths in array.
# If array is empty, return the empty string ('').
#
def common_prefix(paths)
return '' if paths.empty?
return paths.first.split('/').slice(0...-1).join('/') if paths.length <= 1
arr = paths.sort
first = arr.first.split('/')
last = arr.last.split('/')
i = 0
i += 1 while first[i] == last[i] && i <= first.length
first.slice(0, i).join('/')
end
@tsboh
Copy link

tsboh commented Aug 9, 2018

An old(er) post solved this with a one-liner: https://www.ruby-forum.com/topic/120401 :

list = <<-EOS
item001
item004
item002
item002b
item002C
item 5
item 10
itemize this
EOS

/\A(.*).*(\n\1.*)*\Z/.match(list)[1] => "item"

Works with paths aswell, with one remark, the found prefix could turn out not to be a complete existing path,
/Users/xxx/Documents/scans
/Users/xxx/Documents/scans/quarantaine
/Users/xxx/Dropbox/books

results in: /Users/xxx/D
which is not a valid path.

Which can be solved with:

`# Assumption here is obvious, all paths do exists!

def common_prefix(paths)
  return '' if paths.empty?
  return File.dirname(File.join(/\A(.*).*(\n\1.*)*\Z/.match(paths.join("\n"))[1], "/"))
end

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment