https://kotlinlang.org logo
Title
a

Ankush

05/26/2022, 6:19 PM
#getting-started - I am new to Kotlin and trying to absorb as much as possible. I have a requirement where I have a Multi-Level List that I need to parse up to 4 levels. List<List<List<List<String>>>>. The typical way would be using 4 for loops and keep iterating, but I am looking for a smarter Kotlin way of doing it. Could you guys please help me get there?
for(a in As){
    for(b in Bs){
        for(c in Cs){
            for(d in Ds){
                
            }
        }
    }
}
Another train of thought I have is to use flatMap() to flatten the last loop and drop the loops from 4 to 3. But there too, am getting beaten up by Kotlin syntax. Any help is appreciated! TIA 🙂 EDIT: Sturcture is of complex type in nature:
data class A(
    val b: List<B>
)
data class B(
    val c: List<C>
)
data class C (
    val d: List<D>
        )
data class D(
    val string1: List<String>,
    val string2: String
)
🙂 1
c

Casey Brooks

05/26/2022, 6:23 PM
Definitely a gross data structure, but you can call
.flatten()
multiple times to reduce the list down to a single
List<String>
val deeplyNestedList: List<List<List<List<String>>>> = TODO()
val flatList: List<String> = deeplyNestedList
    .flatten()
    .flatten()
    .flatten()
e

ephemient

05/26/2022, 6:24 PM
I'd go a bit further and say that if you're iterating, you should do so over the sequence,
for (x in deeplyNestedList.asSequence().flatten().flatten().flatten()) {
    println(x)
}
which avoids constructing all the partially-flattened lists along the way
a

Ankush

05/26/2022, 6:33 PM
@Casey Brooks, can't agree more! Worst DS till date. My Bad! @Casey Brooks & @ephemient Structure is of complex nature - data class object. Parsed via JSON API call:
data class A(
    val b: List<B>
)
data class B(
    val c: List<C>
)
data class C (
    val d: List<D>
        )
data class D(
    val string1: List<String>,
    val string2: String
)
Will update the query too. Any suggestion for this type of structure?
e

ephemient

05/26/2022, 6:36 PM
for ((string1, string2) in listOfA.asSequence().flatMap { it.b }.flatMap { it.c }.flatMap { it.d }) // ...
a

Ankush

05/26/2022, 7:10 PM
@ephemient, tried it but getting the following error:
Type inference failed:

fun <T, R> Sequence<T>.flatMap
            (
    transform: (T) → Sequence<R>
)
: Sequence<R>
cannot be applied to

        receiver: Sequence<A>?
arguments:
(
        (A) → List<B>?
)
do you think there is a way out of here? If not, could you point me to more relevant documentation?
e

ephemient

05/26/2022, 7:14 PM
where is the nullable coming from, you don't have that in your question
but Kotlin has an
.orEmpty()
extension on collections
a

Ankush

05/26/2022, 7:16 PM
data classes definitions are defined with type ?
Yes, in vanilla for() I used: for(a in As.orEmpty)
e

ephemient

05/26/2022, 7:17 PM
well you can do that in
flatMap
too
a

Ankush

05/26/2022, 7:18 PM
Yes, still got the same error.
e

ephemient

05/26/2022, 7:24 PM
make a real example, then. because what I said does work. https://pl.kotl.in/DQ9EDl_js
a

Ankush

05/26/2022, 7:37 PM
do you mind checking the URL you shared, I added a piece right below it.
e

ephemient

05/26/2022, 7:39 PM
changes are not shared. you need to create another URL
a

Ankush

05/26/2022, 8:25 PM
@ephemient, shared a link. Let me know if it makes sense.