FrontPage  Index  Search  Changes  Login

RubyMemo

自然順ソート

Rubyで自然順ソート。 文字列の数値部分を人が見て自然と思える順番にソートするというもの。

そういえば昔、似たようなソートをやったことがあるなあと思ってコードを探 してみた。単純なつくりだが、ほとんどの場合はこれでじゅうぶん。

sortproc = Proc.new {|a, b|
  cmp = a.gsub(/(\d+)/) {"%05d" % $1.to_i} <=>
    b.gsub(/(\d+)/) {"%05d" % $1.to_i}
  if cmp == 0
    a <=> b
  else
    cmp
  end
}

p %w(2.txt 11.txt 1.txt).sort(&sortproc)
# => ["1.txt", "2.txt", "11.txt"]

p %w(a2.txt a11.txt a1.txt).sort(&sortproc)
# => ["a1.txt", "a2.txt", "a11.txt"]

ようするに、数字部分の桁数を揃えて、普通に文字列ソートしてしまえば良い じゃん、という発想。

IPアドレスからホスト名を得る

CGI で得られる REMOTE_ADDR (ようするに '192.168.1.1' のようなIPアドレスの文字列) から、ホスト名を得る方法。

 remote_addr = '192.168.1.1'
 packed_addr = remote_addr.split('.').collect {|x| x.to_i}.pack 'C4'
 begin
   host, = Socket.gethostbyaddr(packed_addr)
 rescue
   host = remote_addr
 end

IPアドレス文字列を pack で変換した後、Socket.gethostbyaddr で名前解決する。 名前解決できない場合は例外が発生するので、捕捉して元のIPアドレス文字列をホスト名とする。

たいしたネタではないが、割と使うのでメモ。

Hash#indexesの互換性問題

Ruby 1.6系から1.8系への変更で、Hash#indexesがobsoleteになり、Hash#values_atという名前にかわりました。 1.8でもHash#indexesは残っていますが、警告が出まくるので事実上使えません(個人的には、このような互換性のなさはRubyの欠点だと思っています)。 Ruby 1.6 でも 1.8 でも動くスクリプトを書くために、以下のようなコードをスクリプトの冒頭に入れておくと良いです。

unless Hash.method_defined? :values_at
  class Hash
    alias values_at indexes
  end
end

これで Ruby 1.6 でも values_at が使えるようになります。

Last modified:2005/11/26 16:13:30
Keyword(s):
References:[FrontPage]