No Programming, No Life

プログラミング関連の話題や雑記

「このキーワードに投稿した人は、こんなキーワードにも投稿しています」 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だったらキーワード名で同一性を見ればいいんじゃないかなと。