Home > Software engineering >  Kotlin - Converting a List of one data class to another in an Elegant way
Kotlin - Converting a List of one data class to another in an Elegant way

Time:03-04

I have the following data classes

data class Ad(
    val adId: Int,
    val picId: Int
)

data class AdResult(
    val status: StatusCodes,
    val adId: Int,
    val picId: Int
)

enum class StatusCodes(val code: String){
    SUCCESS("SUCCESS"),
    NO_FOUND("NOT_FOUND")
}

In the main function I have

fun main() {
    val ad1 = Ad(15,7)
    val ad2 = Ad(29,9)
    val ads = listOf<Ad>(ad1, ad2)
    val statusCode = StatusCodes.SUCCESS

    val adResults = mutableListOf<AdResult>()
    ads.forEach{
        val adResult = AdResult(statusCode,it.adId,it.picId)
        adResults.add(adResult)
    }
    
    println(adResults)
    
}

Is there any elegant way to create adResults without forEach?

CodePudding user response:

Use the map function:

val adResults = ads.map { AdResult(statusCode, it.adId, it.picId) }

This does literally the same.

CodePudding user response:

In addition to using .map, you could also create a function inside the Ad class that will generate an AdResult. Or alternatively, a function in the companion object of AdResult that will ingest an Ad.

data class Ad(
    val adId: Int,
    val picId: Int
) {
    //v1
    fun toAdResult(statusCode: StatusCodes) = AdResult(statusCode, adId, picId)
}

data class AdResult(
    val status: StatusCodes,
    val adId: Int,
    val picId: Int
){
    companion object{
        //v2
        fun fromAd(status: StatusCodes, ad: Ad) = AdResult(status, ad.adId, ad.picId)
    }
}

You can use them like this:

//v1
val adResults = ads.map { it.toAdResult(statusCode) }

//v2
val adResults = ads.map { AdResult.fromAd(statusCode, it) }

In your actual example the simple way of just making a call to the constructor inside a map() will work just fine, but one of these 2 might be more appropriate if you are doing this in multiple places.

  • Related