1

I have a wrapper that may or may not contain data:

class EmailAdapter {
...
    fun toEmail(): Optional<Email> {
        val agencyContact = getAgencyContact()
        return if (agencyContact.isPresent) {
            Optional.of(Email(
                contact = agencyContact.get()
            ))
        } else {
            Optional.empty()
        }
    }
}

I group one user to multiple contacts:

fun upsertAll(eMails: List<EmailAdapter>) {

    val mailsByUser = eMails
        .filter { adapter -> adapter.getUserContact().isPresent }
        .filter { adapter -> adapter.getAgencyContact().isPresent }
        .groupBy { adapter -> adapter.getUserContact().get() }

It groups val mailsByUser: Map<String, List<EmailAdapter>>
I want to group all emails to a unique user
I want to unwrap the EmailAdapter so that the relation is EmailAdapter.user -> List<EmailAdapter.mail> or val mailsByUser: Map<String, List<Email>>

I fail in the last step - on a conceptual level.

nykon
  • 504
  • 4
  • 18
  • not sure of the use of word marshaling there, but did you mean that you are looking to `mapValues` to result into `val mailsByUser: Map>` ? If you are familiar with java's API, then [this Q&A](https://stackoverflow.com/questions/34642254/what-java-8-stream-collect-equivalents-are-available-in-the-standard-kotlin-libr) might help. – Naman Apr 25 '21 at 15:10
  • I tried to clarify, thank you for the feedback. Yes, the result I'm trying to achieve is `val mailsByUser: Map>` – nykon Apr 25 '21 at 15:13

1 Answers1

1

Does this work for you (first attempt at Kotlin) ?

var mailsByUser = eMails
    .filter { adapter -> adapter.getAgencyContact().isPresent }
    .filter { adapter -> adapter.getUserContact().isPresent }
    .groupBy { adapter -> adapter.getUserContact().get() }
    .mapValues { adapter -> adapter.value.map { ea -> ea.toEmail().get() } }

Conceptually this requires another filter/exception handling for empty optional via toEmail. Similarly one of your methods could be simplified as

fun toEmail(): Optional<Email> {
    return getAgencyContact()
        .map { ac -> Email(contact = ac) } // use of 'map' here
}
Naman
  • 27,789
  • 26
  • 218
  • 353
  • 1
    Oh wow, you did it. mapValues was what I was looking for, thank you so much. `Returns a new map with entries having the keys of this map and the values obtained by applying the transform function to each entry in this Map. The returned map preserves the entry iteration order of the original map.` – nykon Apr 25 '21 at 15:37