Home > Blockchain >  How to retrieve nested values from complicated data class in kotlin
How to retrieve nested values from complicated data class in kotlin

Time:10-13

I'm new to Kotlin, I encountered the problem as follow. The structure of the data class is a bit complicated.

I need to write a function in data class offerSystem to build the whole MyContent class.

My question is I want to pass value of language in Offer and title in OfferDescription to language and title in ContentItem respectively, but I do not know how.

data class OfferSystem(
    val id: String,
    val offers: List<Offer>
)

data class Offer(
    val offerType: String,  
    val offerDescription: List<OfferDescription>,
    val language: Locale
)

data class OfferDescription(
    val title: String,
    val content: String
)

I want to set value for one of the variables(contents) in a data class MyContent. The contents itself is a list of ContentItem, which has several variables.

data class MyContent( // there are other val here 
    val contents: List<ContentItem>
)


data class ContentItem(
    val title: String,
    val language: Locale,
)

I tried

data class OfferSystem(
    val id: String,
    val offers: List<Offer>
){
  fun toMyContent(): MyContent {
    return MyContent(
           ...
           contents = listOf(ContentItem(title = ???, language = ???))
           ...
           )
  }
}

I have no idea how to extract language and title

CodePudding user response:

I'm not sure why offerDescription is a list but you'll have to iterate one way or another, perhaps like this:

contents = sequence {
    offers.forEach { offer -> 
        offer.offerDescription.forEach -> { description ->
            yield(ContentItem(description.title, offer.language)
        }
    }
}.toList()

CodePudding user response:

You need to iterate on the nested collections in order to build your ContentItem values.

You can decompose the work by first writing how to build a list of ContentItem from a single offer (one item for each description):

fun Offer.toContentItems() = offerDescription.map { ContentItem(it.title, language) }

Then you can use flatMap to create a flat list of items out of something that would normally create a list of lists. In your case, you have a list of Offers, and each of them can generate a list of ContentItems:

data class OfferSystem(
    val id: String,
    val offers: List<Offer>
){
  fun toMyContent(): MyContent {
    return MyContent(
        contents = offers.flatMap { it.toContentItems() }
    )
  }
}

Note that this approach creates intermediate collections (unlike the sequence approach provided by @squirrel), so if you have many many items in your lists, you might want to go with a sequence isntead.

CodePudding user response:

Firstly you will need to add the another fields that won't be set in this conversion as null (adding String? = null for example)

After you can do:

var offers: MutableList<Offers>? = null
contents.forEach {

offers.add(Offer(
language = it.language,
offerDescription[0].title = it.title
))
}

So you will be able to add set the offers created to your OfferSystem class

var offerSystem = OfferSystem(offers = offers.toList())
  • Related