perlでちょっと複雑なソート
まただいぶ間が空いてしまった。
その間に私は、基本情報技術者という資格試験を受けたり、引っ越したりしていた。
最近少し落ち着いてきたし、間が空きすぎるのもよくないので、余りネタはないものの何か書いてみようと思う。
数か月前、excelでちょっと複雑なソートをやってみた。
studies.hatenablog.com
今回は、これをperlでやってみよう。
#! /usr/bin/perl use 5.010; while (<>) { ($city, $pref) = split; $pref{$city} = $pref; $pref_priority{$pref} //= ++$count; $city_priority{$city} = ++$times{$pref}; } for (sort {$pref_priority{$pref{$a}} <=> $pref_priority{$pref{$b}} or $city_priority{$a} <=> $city_priority{$b}} keys(%pref)) { printf "%-15s%s\n", $_, $pref{$_}; }
市区町村から都道府県へのハッシュ、都道府県の優先度を表すハッシュ、同じ都道府県のとき市区町村の優先度を表すハッシュ、同じ都道府県が現れた回数を記録するハッシュの4つを用意する。
defined-or演算子を用いて、都道府県の優先度が設定されていない時(つまり一度だけ)優先度を設定する。
市区町村の優先度は、都道府県が現れた回数として設定する。
最後に、宇宙船演算子を用いてソートのルールを指定する。
複数のルールがあるときは、orでつなげばOK。
実行画面はこうなる。
$ cat city.txt 京都市 京都府 千代田区 東京都 高岡市 富山県 松本市 長野県 宮津市 京都府 川崎市 神奈川県 諏訪市 長野県 渋谷区 東京都 滑川市 富山県 新宿区 東京都 臼杵市 大分県 稚内市 北海道 氷見市 富山県 いわき市 福島県 長野市 長野県 横須賀市 神奈川県 宇治市 京都府 $ ./sort.pl city.txt 京都市 京都府 宮津市 京都府 宇治市 京都府 千代田区 東京都 渋谷区 東京都 新宿区 東京都 高岡市 富山県 滑川市 富山県 氷見市 富山県 松本市 長野県 諏訪市 長野県 長野市 長野県 川崎市 神奈川県 横須賀市 神奈川県 臼杵市 大分県 稚内市 北海道 いわき市 福島県
ありゃ、なんかズレた。
今回はちょっとおしゃれ(?)にハッシュを多用して書いてみた。
しかし、ちょっと調べたところによれば、
use 'stable';
などと書けば、perlでも安定ソートを使うこともできるようだ。
普通に1行ずつ配列に格納して、一気にバーンとソートしたほうがもっと短く(易しく)書けるだろう。