Home > Blockchain >  Kotlin functional programming keep reference of previous object in List
Kotlin functional programming keep reference of previous object in List

Time:11-19

I have a list of Person objects which are related to each other with spouse relation in the order of which they appear in the list.

enum class Gender {
    MAN, WOMAN
}
data class Person(val name: String, val age: Int, val gender: Gender)

In the list, each Person with Gender MAN is the spouse of the following Person with WOMAN Gender (and vice versa) and each entry in the list is followed by alternating genders with MAN gender be the first.

The list should ideally be like [MAN, WOMAN, MAN, WOMAN, MAN, WOMAN] (obviously it will be a list of Person objects for simplicity I am putting a list of Gender here) but it could also be like [WOMAN, MAN, WOMAN, MAN, WOMAN, MAN]. In the latter case, the first appearing WOMAN is the spouse of the last appearing MAN.

How this second case could be handled in kotlin by using functional programming. My current approach involves checking if the first Person has a gender women then i remove the first and last objects in the list and then add them in the end but this is not fully a functional programming solution.

Anyone can guide me about that?

Thanks

CodePudding user response:

What do you mean by fully functional approach?
Similar to what you mentioned, you can fix the order by a simple statement like this:

val correctList = if(list.first().gender == MAN) list else list.drop(1)   list.first()

CodePudding user response:

If you want a more general approach, you can do something like this:

    // separate the people into a list of gender=MAN and a list of everyone else
    // the result is a Pair, so I'm destructuring that into two variables
    val (men, women) = people.partition { it.gender == MAN }
    // use zip to take a person from each list and combine them into a list of pairs
    men.zip(women)
    // use flatMap to turn each pair into a list of two people
    // just using map would create a list of lists, flatMap flattens that into
    // a single list of people, alternating gender=MAN, gender=WOMAN 
       .flatMap { it.toList() }

This way it doesn't matter how your original list is ordered, it can start with any element and you can have the different types completely mixed up - BABBAABA will still come out as ABABABAB. So it's a general way to combine mixed data streams - partition separates them into groups, and zip lets you take an element from each group and do something with them.

Here I'm just letting zip create Pairs, and then flatMap turns those back into an ordered list (if that's what you want). You could also do a forEach on each pair instead (say if you wanted to set a value on each Person to link them to each other), or zip can take a transform function too.

Also zip terminates when one of the lists runs out (e.g for AAA and BB you'll get two pairs) so this works for generating complete pairs of elements - if you also needed to handle elements without a "partner" you'd need to do a bit more work

  • Related