「このキーワードに投稿した人は、こんなキーワードにも投稿しています」 for はてなハイクをGroovyで書いてみた
以前、何かを受信したときのアイデアをコードに起してみた。
ソース Powered by HatenaHaiku4J
import hatenahaiku4j.* import hatenahaiku4j.util.* def baseKeyword = 'ひとりごと' def list = konnaKeyword(baseKeyword, 20, 10) println ('*' * 20) println "[[${baseKeyword}]]に投稿した人は、こんなキーワードにも投稿しています。 (${list.size()}件取得)" println ('-' * 20) list.each{ println it } println ('-' * 20) /** * こんなキーワードのリストを取得。 * サンプリング人数を増やしすぎると * とても時間がかかります。 */ def konnaKeyword(baseKeyword, limit = 10, samplingUser = 3) { def apiLight = new HatenaHaikuAPILight() def base = apiLight.getKeywordTimeline(baseKeyword) def users = base*.user.unique{ a, b -> a.userId <=> b.userId } def keywordList = [] print "サンプリング開始 (${samplingUser}人分) " users[0..<([samplingUser, users.size()].min())].each { user -> keywordList.addAll(user.api.getTimeline()*.keyword - baseKeyword) print '.' } println '' println "${limit}件取得" keywordList.groupBy{ it }.collect{ [it.key, it.value.size()] }.sort{ -it[1] }.with{ it[0..<[limit, it.size()].min()] }*.getAt(0) }
動き
とりあえずサンプルなのでキーワード「ひとりごと」に対して書き込みをした人から数人サンプリングして、結果を出力しています。
備考
hatenahaiku4j.Userとかの#equalsメソッドをちゃんと実装してあげたほうがいい気がした。
そうしないと、{ a, b -> a.userId <=> b.userId } とかしないといけないから若干面倒な気がする。
たとえばhatenahaiku4j.UserだったらユーザIDで同一性を見ればいいだろうし、hatenahaiku4j.Keywordだったらキーワード名で同一性を見ればいいんじゃないかなと。