それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

文字列の差をから共通部分を&で求めてみる String#&

文字列を頭から比べて、同じところだけを取出したいとき

"/home/takuya/2010-09-10" & "/home/takuya/test.rb" #=> "/home/takuya/"

のようなことがしたいわけです.何に使うか分らないけど,URLの共通部分や,ファイルのパスの頭の部分で一致する箇所を調べたいわけです

URLの共通部分を求める
"http://d.hatena.ne.jp/takuya_1st/archive?word=ruby"
& "http://d.hatena.ne.jp/takuya_1st/searchdiary?word=ruby"
#=> "http://d.hatena.ne.jp/takuya_1st/"

とかで一瞬にしてディレクトリを共通部分を見つけるとか

適当なファイル名をなんとかする
"httpd.conf.test.bak" & "httpd.conf.bak.2011-09-10" & "httpd.conf" #=> "httpd.conf"

みたいな事をしたいわけです.

たとえば表記揺れとか

タイトルの表記揺れを無視して共通部分が欲しい

a="3月のライオン (1) (ジェッツコミックス) 羽海野 チカ "
b="3月のライオン 6 (ジェッツコミックス) 羽海野チカ "
puts a-b  #=>""3月のライオン "

ファイルのフルパスを求めてディレクトリが共通か調べるのに diranme つかったり,でたどるのも面倒だし.Amazonの検索結果が適当すぎて,マンガのタイトルの共通部分を見つけるのが面倒だし.

文字列の共通部分を返す

class String
  def &(str)
    k = $KCODE
    $KCODE='u'
    a = self.split(//).zip(str.split(//)).select{ |e| e.uniq.size==1 }.map{|e| e[0]}.join
    $KCODE= k
    a
  end
end

という感じで,作ってみた.ファイルパス関連の処理やタイトルの処理で威力を発揮すると思う.


もう split '/' してディレクトリ調べなくて良いんですよ

2012-01-21追記

前のやり方だと

"/var/www" & "/etc/www” # => "//www” 

になる。これはこれで正しいんだけど。 & の意味が共通和だからね。


実際には、文字列の共通「部分」を前方一致が便利だと分かったので。前方一致に特化することにした。

文字列を先頭から共通する最短文字列を探す

class String
  def &(str)
    k = $KCODE
    $KCODE='u'
    a = self.split(//).zip(str.split(//)).map{ |e| e.uniq.size==1 }
    idx = a.index(false)
    return "" if idx == nil
    return self[0...idx]
    $KCODE= k
  end
end
"/var/www" & "/etc/www” # => "//www”  ←改良前
"/var/www" & "/etc/www" # => "/" ←改良後


この方が、Amazonのコミックには使いやすそうだ。