First, my apologies, I couldn't tag this as kotlin and I figured Java was the next closest thing. This is homework, I'm not looking for someone to do it for me, just a little help. So the first thing is that I've got a sealed interface with some subclasses (all required to be like this, this part can't change)

sealed interface Mammal{
    abstract val name: String
    abstract val age: Int
    abstract val friends: List<Mammal>
}

data class Human(override val name: String = "",
                 override val age: Int,
                 val nickName: String,
                 override val friends: List<Mammal> = emptyList()
                ) : Mammal

data class Dog(override val name: String,
               override val age: Int,
               val favoriteTreat: String,
               override val friends: List<Mammal> = emptyList()
              ) : Mammal

data class Cat(override val name: String,
               override val age: Int,
               val numberOfMiceSlain: Int,
               override val friends: List<Mammal> = emptyList()
              ) : Mammal

Then I've got some functions, which are required to be top-level extension functions on List<Mammal>. I think if I just have help with one, the rest will fall in line and make more sense, so this is the one I'd like help with. The only thing required in the function is fun List<Mammal>.getNamesAndFriendsAges(){}, the rest is me fighting with it trying to make it work. This should return

//  Names and sums of their friends' ages
//      Fido=229
//      Blackie=55
//      Patrick=148

And this is what I have so far (this is the part I need help with).

// creates a map of the name of each mammal and the sum of the ages of their friends
fun List<Mammal>.getNamesAndFriendsAges(): Map<String, Mammal> {
    return this
       // .flatMap { it.friends.groupBy { it.name } }
        //.groupBy { it.name }
     //   .associateBy{it.name + it.friends + sumOf { it.age }}
     //   .associateBy{it.name + sumOf { it.age }}
     //   .associateBy { it.name }
        .sortedBy { it.name }
        .flatMap { it.friends }
        .associateBy { it.name }
}

And this is the important part of main (none of which can change):

    fun main() {
        val mammals = listOf(
            Dog("Fido", 1, "Gravy Train",
                friends = listOf(
                    Human("Scott", 53, "Scooter"),
                    Human("Steven", 53, "Steve"),
                    Cat("Thunderbean", 10, 42),
                    Cat("Puffball", 101, 13),
                    Dog("Fifi", 5, "Milk Bone"),
                    Dog("Rover", 7, "Real Bone")
                )
            ),
            Cat("Blackie", 2, 22,
                friends = listOf(
                    Human("Mike", 23, "Mikey"),
                    Human("Sue", 26, "Susie"),
                    Cat("Thing", 5, 3),
                    Cat("Little One", 1, 0)
                )
            ),
            Human("Patrick", 79, "Jean Luc",
                friends = listOf(
                    Human("Ian", 80, "Gandalf"),
                    Human("Hugh", 51, "Wolverine"),
                    Cat("Q", 5, 3468),
                    Dog("Worf", 12, "Gagh")
                )
            )
        )

        println()
        println("Names and sums of their friends' ages")
        mammals.getNamesAndFriendsAges().forEach { println("    $it") }

    }

Hello EmiLynn, here are a couple of hints for you.

  1. Your teacher's instruction says to return a map of the name of each mammal and the sum of the ages, so you need to return Map<String, Int> instead of Map<String, Mammal>. This will allow the compiler to help you out.
  2. I am not sure why the sortedBy() is used here. You did not tell us that it is a requirement. Remove it if it's not needed because it can further confuse you.
  3. The equivalence of Java Stream peek() in Kotlin would be onEach(). You can add onEach() after each intermediate step to print out the current values; this would greatly help with debugging, so you can see how your data structure mutates.
  4. Write down in English what needs to happen at each step if you want to transform List<Mammal> into Map<String, Int>; draw pictures if you need to. Code each step with simple functions. Create temporary data structures, etc. You do not have to use fancy operators like associateBy() at first. After you have successfully produced the result with simple functions, read through the list of operators again to see how you can simplify your code with only one or two operators.
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.