How to process future stream to create an instance

2019-06-06 08:19发布

I have a method that is takes in a future as parameter and also has a future inside it. I want to create a list from this method such that it takes values from the future that is passed in.

Case Classes

case class Color (colorName: String)
case class Shade (shadeName: String)
case class ColoShade (color: Color, shades: List[Shade])

Methods

val shadesFuture: Future[Seq[Shade]] = {
    val larSource: Future[Seq[LoanApplicationRegister]] =
      getMySource(ctx, id)
        .map(_.utf8String)
        .map(_.trim)
        .map(s => ShadeParser(s))
        .collect {
          case Right(shade) => shade
        }
        .runWith(Sink.seq)
}

//call the method
myMethod(shadesFuture)

//method definition
def myMethod(shadesFuture: Future[Seq][Shade]])
  :Future[ColorShade] {
    colorFuture
      .map(_.utf8String)
      .map(_.trim)
      .map { s =>
        ColorParser(s)
      }
      .collect {
        case Right(c) => c
      }
      .map { c =>  
         //How can I make an instance of ColorSade here? 
         //I tried 
         val colorShade = ColorShade(c, shadesFuture) 
         //but this doesn't work  

         //I would like to change this to instead be someOtherMethod(colorShade.c)
         someOtherMethod(c) 
      }
}

Question

How can I correctly return ColorShade from myMethod such that the shades property is the output from the passed in parameter shadesFuture?

1条回答
Emotional °昔
2楼-- · 2019-06-06 08:41

I am not sure I understand what you mean ... But I think you are looking for something like this:

 def myMethod(shadesFuture: Future[Seq[Shade]]) : Future[ColorShade] = for {
   shades <- shadesFuture
   color <- colorFuture.map(...) // whatever the transformations you wanted
   transformedColor = ColorParser(color.utf8String.trim) // or you can do them like this

   colorShade = ColorShade(color, shades)
   // whatever you wanted to do with it here
   _ = someOtherMethod(colorShade.c, colorShade.shades)
 } yield colorShade // or whatever you need to return. The result of this is `Future[ColorShade]`

This is called "for-comprehension" and is syntactic sure for a bunch of nested .flatMap calls. You could also writer it explicitly (this is not exactly what for-comprehension is desugared into, but functionally equivalent):

 shadesFuture
    .flatMap { shades => 
       colorFuture
         .map(...)  // transform, whatever
         .map(ColorShade(_, shades)
    }  
查看更多
登录 后发表回答