Scala 勉強中なのでXML操作やパターンマッチングなどをATND APIを使って試してみた。

キーワード・イベント開催年月・イベント開催年月日を検索条件にすることができるようにして、
返ってきたXMLからタイトル、開始日時、開催場所を標準出力するようにしてみた。
引数を複数渡して、yyyyMM形式ならymパラメータに、yyyyMMdd形式ならymdパラメータに、
どちらにもマッチしないならkeywordパラメータに渡すことにした。
(数値が6個か、8個かでパターンマッチングしているので厳密には正しい日付かどうかチェックできていないけど)
で、試行錯誤の結果、こんな感じ。
import scala.collection.mutable.ListBuffer
import scala.io.Source
import scala.xml.XML

import java.text.SimpleDateFormat

val source = Source.fromURL("http://api.atnd.org/events/?" + getParams(args))
val response = XML.loadString(source.mkString)

val orgFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
val showFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm")

response \\ "event" foreach { e =>
    println("『%s』\n  %s\n  %s\n" format(
	e \\ "title" text,
	showFormat.format(orgFormat.parse(e \\ "started_at" text)),
	e \\ "place" text))
}

def getParams(args:Array[String]):String = {
	val keywordList = new ListBuffer[String]
	val ymList = new ListBuffer[String]
	val ymdList = new ListBuffer[String]
	
	val ymPattern = """^(\d{6})$""".r
	val ymdPattern = """^(\d{8})$""".r
	
	args foreach { arg =>
		arg match {
			case ymPattern(ym) => ymList += ym
			case ymdPattern(ymd) => ymdList += ymd
			case _ => keywordList += arg
		}
	}
	
	val paramsList = new ListBuffer[String]
	if (!keywordList.isEmpty) {
		paramsList += "keyword=" + keywordList.mkString(",")
	}
	if (!ymList.isEmpty) {
		paramsList += "ym=" + ymList.mkString(",")
	}
	if (!ymdList.isEmpty) {
		paramsList += "ymd=" + ymdList.mkString(",")
	}
	
	paramsList.mkString("&")
}
…うーん、可変リストを多用している時点であんまりイケてないように思う。
リスト内包表記でymPatternにマッチするもの、ymdPatternにマッチするもの、
どちらにもマッチしないものをそれぞれ取り出すようにすることも考えたが、
そうするとリストを3回回すことになるのでそれもイマイチ。

一応期待通りに動いてはいるけど、まだまだ改善できそうな気がするなあ。

【追記】partition を使用した改良版を書きました。

Copyright© 2011-2021 Shunsuke Otani All Right Reserved .