代码之家  ›  专栏  ›  技术社区  ›  MedicineMan

工作时如何优雅地归还地图

  •  0
  • MedicineMan  · 技术社区  · 5 年前

    我是来自Java的Scala新手,从这个函数优雅地返回Map时遇到了困难。重写这个函数的优雅方式是什么,这样它就不会有如此糟糕的重复?

        val data = getData
        if (someTest(data)) {
            val D = doSomething(data)
            val E = doWork(D)
            if (someTest2(E)) {
                 val a = A()
                 val b = B()
                 Map(a -> b)
            } else {
               Map.empty
            }
        } else {
            Map.empty
        }
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   Andrey Tyukin    5 年前

    如果您在连接太多条件时遇到问题 && ,你可以把所有的东西都放进自然短路的单子(即 Option ),表演一堆 filter map -按步骤,将结果替换为 Map(A() -> B()) 如果所有测试都成功,然后打开 选项 用一个 getOrElse 最后:

    Option(getData)
      .filter(someTest)
      .map(doSomething andThen doWork)
      .filter(someTest2)
      .map(_ => Map(A() -> B()))
      .getOrElse(Map.empty)
    

    通过这种方式,您可以“更垂直地”组织代码。

        2
  •  1
  •   Tim    5 年前

    安德烈的回答是正确的,但逻辑也可以用 for 声明:

    (for {
      data <- Option(getData) if someTest(data)
      d = doSomething(data)
      e = doWork(d) if someTest2(e)
    } yield {
      Map(A() -> B())
    }).getOrElse(Map.empty)
    

    这更多地保留了代码的原始形式,但使用哪个版本是一个品味问题。你也可以把 if 如果这能让事情变得更清楚的话,请另排一行。

    请注意,我保留了 d e 假设它们在实际代码中是有意义的。如果不是的话,那么可能只有一个 如果 完成所有测试的表达式,如其他答案所述:

    (for {
      data <- Option(getData)
      if someTest(data) && someTest2(doWork(doSomething(data)))
    } yield {
      Map(A() -> B())
    }).getOrElse(Map.empty)
    
        3
  •  0
  •   C.S.Reddy Gadipally    5 年前

    如果你用Map向else块提及,你可以重写以利用短路。像重复一样空虚。

    val data = getData
    if (someTest(data) && someTest2(doWork(doSomething(data)))) {
      val a = A()
      val b = B()
      Map(a -> b)
    } else {
        Map.empty
    }
    

    使用惰性评估的第二个解决方案:

    val data = getData
    lazy val D = doSomething(data)
    lazy val E = doWork(D)
    
    if (someTest(data) && someTest2(E)) {
      val a = A()
      val b = B()
      Map(a -> b)
    } else {
      Map.empty
    }
    

    D、 如果someTest(数据)为false,则不会对E和someTest2(E)进行评估。