今日のお題は『一定の規則で並んだテキストをプログラムで処理して並び替える』というものです。こうした処理は、定型処理によくあるものです。基本的な方法を学ぶことで、いろいろなデータに応用できます。さっそく、詳しいお題を確認してみましょう。

FBで実際にあった依頼

なお、今回のお題は、Facebookで見つけたものです。日本のオープンソース界を大いに盛り上げているびぎねっとの宮原さんが「一杯奢る」のでプログラムを作って欲しいと書き込んでいたものです。それは、以下のようなものでした。

以下のような4行でひとまとまりのデータを表すテキストファイルがあります。これを日付順(新しい順)に並び替えるプログラムを作ってください。

日付1
タイトル1
URL1

日付2
タイトル2
URL2

日付3
タイトル3
URL3

...

これを図にしてみると、以下のようになります。

  • テキストデータの構造

    テキストデータの構造

筆者は「これならすぐ作れるし、いつもお世話になっているから作ろう!」と思ったのです。しかし、いつもみんなのために頑張っている宮原さんのため、あるいは「一杯奢る」の威力が凄かったため(?)、あっという間に、たくさんの方がこの問題を解いてしまっていました。

とは言え、この手のネタは定期的にあるものです。そこで、読者の皆さんと一緒に、プログラムを作って、次回奢ってもらえる機会に備えることにしましょう!

ポイントはデータを一つずつ分けて配列に入れること

そもそも、手元のテキストデータを任意の順番で並び替えたいという場面は意外と多いものです。それでは、この問題をなでしこで解いていきましょう。

こうしたテキストのデータを処理する場合、だいたい一つのデータが一行になっているものが多いものです。その代表的なデータが、CSV形式のデータです。しかし、今回のお題のデータでは、四行ごと(三行のデータ+空行)で、一つのデータとなっています。この特徴を掴んで、データを二次元配列に変換して処理するとうまく処理できます。一度、配列変数に変換する理由ですが、なでしこの内部形式である配列形式にしてしまえば、並び替え(ソート)などのデータ処理が容易になるからです。

手順を図にしてみると、以下のようになります。テキストデータを二次元配列変数に変換し、そこで並び替えなどの処理を行います。そして、処理後にテキスト形式で出力するという手順です。

  • データを一度二次元配列にすると処理しやすい

    データを一度二次元配列にすると処理しやすい

ただし、筆者の経験上、この手のデータは手動で作成するため、データがたくさんあると正しく四行ずつになっていることは希です。どういう事かと言うと、途中に間違って入力した不完全なデータ(日付とURLだけでタイトルが抜けている、または、無駄な改行が多く含まれている)が紛れ込んでいることが多くあるからです。そのため、データの間違いをチェックする機構も一緒に作ることが多いです。ですが、今回はプログラムをシンプルにするために、多少壊れたデータでも対処できる仕組みを考えてみます。

このデータの並びですが、よくよく見ると、各データの区切りに改行が二つあるという点に注目できます。そこで、改行二つを区切り記号にして区切れば、手軽にデータを分割できます。

以下のプログラムを、なでしこ3Web簡易エディタに貼り付けて実行してみましょう。

サンプル=『2019/07/14
日本語プログラミング言語「なでしこ」
https://nadesi.com

2019/7/1
Ruby
https://www.ruby-lang.org/ja/

2019/07/09
教育用プログラミング言語「ドリトル」
https://dolittle.eplang.jp/
』

# --- テキストデータを二次元配列に変換 --- (*1)
区切り文字=改行&改行
結果=[]
サンプルを区切り文字で区切って反復
  対象をトリムして、改行で区切る。
  それを結果に配列追加。
ここまで。
# --- 日付順に並び替える --- (*2)
「日付順関数」で結果を配列カスタムソート。
●日付順関数(A,B)
  TA = A[0]をUNIXTIME変換
  TB = B[0]をUNIXTIME変換
  それはTB - TA
ここまで。
# --- 結果を表示する --- (*3)
結果を反復
  対象[0]を表示
  対象[1]を表示
  対象[2]を表示
  「」を表示。
ここまで。

プログラムを簡易エディタに貼り付けて「実行」ボタンを押して実行すると、以下のように表示されます。日付に注目してみると、正しく新しい順に並んでいるのを確認できます。

  • プログラムを実行したところ

    プログラムを実行したところ

プログラムを確認してみましょう。プログラムの前半はサンプルデータです。そして、後半が実際のプログラムです。(*1)の部分では、テキストデータを二次元配列に変換します。方法としては、ひとまとまりのデータを改行二つで区切ります。そして、各データを改行で分割するというものです。

そして、(*2)の部分では日付順に並び替えます。大抵のプログラミング言語には、配列を任意の順番で並び替える命令が用意されています。なでしこにも、命令『配列カスタムソート』があります。これを使って、日付順に並び替えます。

最後に(*3)の部分で、二次元配列変数をテキスト形式に変換して出力します。

使いやすくUIを作ろう

さて、ここまでのプログラムで、おおまかなプログラムは完成しました。今度は、プログラムを手軽に実行できるように、操作画面であるUIを作成してプログラムを完成させましょう。

# --- UIの作成 --- (*1)
DOM親要素に『
    <div id="frm">入力:<br>
    <textarea id="input"></textarea><br>
    <button id="conv_btn">変換</button><br>
    <textarea id="output"></textarea></div>
』をHTML設定。
『#frm textarea』に、{"width":"99%", "height":"150px", "background-color":"#FFF0F0"}を、DOMスタイル一括設定。
「#conv_btn」をクリックした時には
  変換処理実行。
ここまで。
# --- 変換処理 --- (*2)
●変換処理実行とは
  「#input」のテキスト取得して、入力データに代入。
  区切り文字=改行&改行
  結果=[]
  入力データを区切り文字で区切って反復
    対象をトリムして、改行で区切る
    それを結果に配列追加。
  ここまで。
  「日付順関数」で結果を配列カスタムソート。
  # --- 出力データを作成する --- (*3)
  F出力=「」
  結果を反復
    F日付=対象[0]
    Fタイトル=対象[1]
    FURL=対象[2]
    F出力=F出力&「{F日付}{改行}{Fタイトル}{改行}{FURL}{改行}{改行}」
  ここまで。
  「#output」にF出力をテキスト設定。
ここまで。

●日付順関数(A,B)
  TA = A[0]をUNIXTIME変換
  TB = B[0]をUNIXTIME変換
  それはTB - TA
ここまで。

上記のプログラムを、同じように、なでしこ3Webエディタに貼り付けて実行してみましょう。そして、入力テキストを「入力:」のすぐ下のテキストボックスに貼り付けて「変換」ボタンを押します。すると、変換ボタンの下に実行結果が表示されます。

  • 手軽に変換を試せるUIを準備したもの

    手軽に変換を試せるUIを準備したもの

プログラムを確認してみましょう。(*1)の部分で操作画面のUIを作成します。ここでは、HTMLをべた書きしてUIを作成しています。なでしこから操作するために、操作したい要素に『id="名前"』のような属性をつけておきます。そうすると、なでしこのプログラムから「#名前」のような名前でDOMオブジェクトを操作できます。

そして、(*2)の部分では、「#input」と名付けたテキストボックスからテキストを取得して、処理を行い、「#output」と名付けたテキストボックスにデータを設定するというものです。整形処理については、一つ目のプログラムとほとんど同じです。異なる点は、(*3)の部分で出力データを文字列で生成するようにしています。もし、データの並び順を変えたい場合には、変数「F出力」の部分の並び方を調整します。

まとめ

以上、今回は、なでしこでテキストデータを並び替えるプログラムを紹介しました。テキスト処理を行う場合は、元のテキストデータを上手に解析して、配列変数に変換するのがポイントでした。

また、ここで作ったプログラムは、ある程度、データが壊れていても、適当にデータを処理できるようにしていますが、より正確なデータが必要な場合には、日付の形式が正しいかどうか簡単なチェックを入れるなど、データの確認機構も入れると親切でしょう。

なお、Facebookのこの投稿には、さまざまな方法で問題を解く方法が書き込まれていて、それを眺めるだけでも面白いものになっていました。また、SNSで面白い投稿を見つけたら、なでしこで解く方法を解説したいと思います。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2005年IPAスーパークリエイター認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。