作記録

記憶代わり

【Kotlin】Collections系の型をMap型に変換する

概要

プロパティや表などを表現する際に、Map型で表現すると便利だと思います。

Collections系の型をMap型に変換する際によく利用するメソッドが associate メソッドです。

associate

既にListなどのCollection系のオブジェクトが存在する際に、そのList型のオブジェクトのリストの値を利用する事によりMap型に変換する事が出来ます。

package associate

import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties

val requestClass: KClass<ProfileRegistrationRequest> = ProfileRegistrationRequest::class

val request = ProfileRegistrationRequest(
    name = "田中太郎",
    age = 18
)

// propertyCollectionには次の配列が入っている -> [val associate.ProfileRegistrationRequest.age: kotlin.Int, val associate.ProfileRegistrationRequest.name: kotlin.String]
val propertyCollection: Collection<KProperty1<ProfileRegistrationRequest, *>> = requestClass.memberProperties

val properties: Map<String, Any> = propertyCollection.associate {
    val key: String = it.name
    val value = it.get(request) ?: throw IllegalStateException("properties does not has key. [key: $key]")
    it.name to value
}

fun main() {
    println(propertyCollection)
    println(properties)
}

実行結果は下記です。

{age=18, name=田中太郎}

associateBy

既にListなどのCollection系のオブジェクトが存在する際に、そのオブジェクトの複数の値を利用する事によりkeyを作成する。valueは、そのオブジェクトの複数の値になる。

package associate

import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties

val requestClass: KClass<ProfileRegistrationRequest> = ProfileRegistrationRequest::class

val request = ProfileRegistrationRequest(
    name = "田中太郎",
    age = 18
)

// propertyCollectionには次の配列が入っている -> [val associate.ProfileRegistrationRequest.age: kotlin.Int, val associate.ProfileRegistrationRequest.name: kotlin.String]
val propertyCollection: Collection<KProperty1<ProfileRegistrationRequest, *>> = requestClass.memberProperties

val properties: Map<Any, KProperty1<ProfileRegistrationRequest, *>> =
    propertyCollection.associateBy {
        // 各プロパティのvalue
        it.get(request)
            ?: throw IllegalStateException("properties does not has key. [key: ${it.name}]")
    }

fun main() {
    println(propertyCollection)
    println(properties)
}

実行結果は下記です。

{18=val associate.ProfileRegistrationRequest.age: kotlin.Int, 田中太郎=val associate.ProfileRegistrationRequest.name: kotlin.String}