Search code examples
scalagroup-byconcurrencyuser-defined-functionsfuture

Using Scala groupBy(), from method fetchUniqueCodesForARootCode(). I want to get a map from rootCodes to lists of uniqueCodes


I want to to return Future[Map[String, List[String]]] from fetchUniqueCodesForARootCode method

    import scala.concurrent._
    import ExecutionContext.Implicits.global  
    case class DiagnosisCode(rootCode: String, uniqueCode: String, description: Option[String] = None)

    object Database {

      private val data: List[DiagnosisCode] = List(
        DiagnosisCode("A00", "A001", Some("Cholera due to Vibrio cholerae")),
        DiagnosisCode("A00", "A009", Some("Cholera, unspecified")),
        DiagnosisCode("A08", "A080", Some("Rotaviral enteritis")),
        DiagnosisCode("A08", "A083", Some("Other viral enteritis"))
      )
    
      def getAllUniqueCodes: Future[List[String]] = Future {
        Database.data.map(_.uniqueCode)
      }


      def fetchDiagnosisForUniqueCode(uniqueCode: String): Future[Option[DiagnosisCode]] = Future {
        Database.data.find(_.uniqueCode.equalsIgnoreCase(uniqueCode))
      }
    }

getAllUniqueCodes returns all unique codes from data List.

fetchDiagnosisForUniqueCode returns DiagnosisCode when uniqueCode matches.

  • From fetchDiagnosisForUniqueCodes, I am returningFuture[List[DiagnosisCode]] using getAllUniqueCodes() and fetchDiagnosisForUniqueCode(uniqueCode).*

      def fetchDiagnosisForUniqueCodes: Future[List[DiagnosisCode]] = {
    
        val xa: Future[List[Future[DiagnosisCode]]] = Database.getAllUniqueCodes.map { (xs: 
            List[String]) =>
          xs.map { (uq: String) =>
            Database.fetchDiagnosisForUniqueCode(uq)
          }
        }.map(n =>
            n.map(y=>
              y.map(_.get))) 
      }
    
      xa.flatMap {
      listOfFuture =>
        Future.sequence(listOfFuture)
     }}
    

Now, def fetchUniqueCodesForARootCode should return Future[Map[String, List[DiagnosisCode]]] using fetchDiagnosisForUniqueCodes and groupBy

Here is the method

def fetchUniqueCodesForARootCode: Future[Map[String, List[String]]] = {
  fetchDiagnosisForUniqueCodes.map { x =>
    x.groupBy(x => (x.rootCode, x.uniqueCode))
  }
}

Need to get the below result from fetchUniqueCodesForARootCode:-

A00 -> List(A001, A009), H26 -> List(H26001, H26002), B15 -> List(B150, B159), H26 -> List(H26001, H26002)


Solution

  • It's hard to decode from the question description, what the problem is. But if I understood correctly, you want to get a map from rootCodes to lists of uniqueCodes.

    The groupBy method takes a function that for every element returns its key. So first you have to group by the rootCodes and then you have to use map to get the correct values.

    groupBy definition: https://dotty.epfl.ch/api/scala/collection/IterableOps.html#groupBy-f68

    scastie: https://scastie.scala-lang.org/KacperFKorban/PL1X3joNT3qNOTm6OQ3VUQ