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 Offer
s, and each of them can generate a list of ContentItem
s:
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())