No Programming, No Life

新しいNPNLです。http://d.hatena.ne.jp/fumokmm/ から引っ越してきました。

Re:階層的なキーの連想配列化

前回のどう書く?org投稿から約1年ぶりくらいで、久々に投稿してみました。

お題: Server error
投稿: Server error

こんな感じになりました

def data = [
  ['東京都', '区部',     '千代田区', 'object1'],
  ['東京都', '区部',     '中央区',   'object2'],
  ['東京都', '区部',     '港区',     'object3'],
  ['東京都', '多摩地域', '支部',     '昭島市',     'object4'],
  ['東京都', '多摩地域', '支部',     'あきる野市', 'object5'],
  ['東京都', '多摩地域', '西多摩郡', '奥多摩町',   'object6'],
  ['東京都', '島嶼部',   '大島支庁', '大島町',     'object7'],
  ['東京都', '島嶼部',   '三宅支庁', '三宅村',     'object8'],
]

def hashTree = this.&toHashMap.curry(0)
def result = hashTree(data)

// 以下テスト
assert result.toString() == '[東京都:[区部:[中央区:object2, 千代田区:object1, 港区:object3], 多摩地域:[支部:[あきる野市:object5, 昭島市:object4], 西多摩郡:[奥多摩町:object6]], 島嶼部:[三宅支庁:[三宅村:object8], 大島支庁:[大島町:object7]]]]'
assert hashTree(data.sort{ Math.random() }) == hashTree(data.sort{ Math.random() })

// ハッシュマップに変換するメソッド
def toHashMap(idx, list) {
  if (idx == list.first().size() - 1) return list.first()[idx]
  def result = [:] as TreeMap // キーで並べ替えるマップ
  list.groupBy{ it[idx] }.each {
    result[it.key] = toHashMap(idx + 1, it.value)
  }
  result
}

動作確認はGroovy Version: 1.6.4 JVM: 1.6.0_13にて。

考察

groupByしてキーを抽出し、map構築を再帰的に繰り返しています。
あと、意味なくカリー化してます(笑)