【问题标题】:Scala - how to refactor a method to use reduceLeft instead of iterating? [closed]Scala - 如何重构方法以使用 reduceLeft 而不是迭代? [关闭]
【发布时间】:2018-10-18 11:11:45
【问题描述】:

我有 Java 背景,最近开始学习 Scala。我已经实现了一个在我看来仍然更像 Java 风格的方法。如何使用各种 Scala 特性将其改进为更像 Scala 的方法?

我有个想法像使用reduceLeft

val sales: List[Sale] = salesList.sortBy(_.timestamp)

sales.reduceLeft(someFunction)

并且该函数可能具有类似于

的签名
  def reduceSalesFunction: (Sale, Sale) => Sale= {
     ???
  }

这是我实现该方法的方式。有改进的空间吗?

def processSales(sales: List[Sale]): Sale = {
    // if just a single sale, get it
    if (sales.size == 1) sales.iterator.next 

    else {
      // get the oldest sale
      val sortedSales = sales.sortWith(_.timestamp < _.timestamp)
      val oldestSale: Sale = sortedSales.min
      val salesMetrics: Metrics = oldestSale.metrics

      // update the oldest sale's metrics
      for (sale <- sortedSales) {
        val metrics: Metrics = sale.metrics
        if (metrics.isMetric_1) salesMetrics.setIsMetric_1(metrics.isMetric_1)
        if (metrics.isMetric_2) salesMetrics.setIsMetric_2(metrics.isMetric_2)
        if (metrics.isMetric_3) salesMetrics.setIsMetric_3(metrics.isMetric_3)
      }

      // if there are metrics with `false` values set the oldest sale's metrics to `false` as well (Metrics is an Enum)
      for (metric <- Metrics.values(); if !salesMetrics.isSet(metric)) {
        salesMetrics.setMetricValue(metric, false)
      }
      oldestSale
    }
  }

【问题讨论】:

  • 您能否添加一些示例输入及其预期结果?
  • 我不能标记它,但这不应该在 codereview.stackexchange 上吗?
  • @JoelBerkeley 我认为你是对的。那我应该从这里删除它吗?
  • 不知道能不能迁移,不过这样啊
  • 我投票决定将此问题作为离题结束,因为问题属于另一个站点 codereview.stackexchange.com。 codereview.stackexchange.com 未显示在另一个站点选项的列表中。

标签: java scala collections


【解决方案1】:

我有一些风格建议给你:

  • 不要调用方法getSomthting它不是getter,我认为是 也适用于 Java。
  • 您可以将if else 替换为模式匹配。

例子:

sales match {
  // if just a single sale, get it
  case x :: Nil => x
  // get the oldest sale
  case other    => //your logic
}
  • 希望使用相同的模式进行类型推断。

选择以下之一:

  val sortedSales: List[Sale] = sales.sortWith(_.timestamp < _.timestamp)
  val oldestSale: Sale = sortedSales.min
  val salesMetrics: Metrics = oldestSale.metrics

或者

  val sortedSales = sales.sortWith(_.timestamp < _.timestamp)
  val oldestSale = sortedSales.min
  val salesMetrics = oldestSale.metrics
  • 尽可能避免在方法/字段命名中使用“_”(isMetric_1)。
  • 不要使用“;”。行分隔的块更具可读性。

例子:

for { 
  metric <- Metrics.values()
  if !salesMetrics.isSet(metric)
} salesMetrics.setMetricValue(metric, false)
  • 另一个好的做法是使用不可变结构。

附注:

这只是我的意见。这取决于你的团队!

我强烈建议您查看https://docs.scala-lang.org/style/

享受 Scala! :)

【讨论】:

  • 不知道能不能用reduceLeft简化成val sales: List[Sale] = salesList.sortBy(_.timestamp)sales.reduceLeft(someFunction)
  • 我认为在你的情况下它可能类似于:sortedSales.reduce { case (acc, sales) =&gt; if (sales.metrics.isMetric_1) acc.metrics.setIsMetric_1(metrics.isMetric_1) if (sales.metrics.isMetric_2) acc.metrics.setIsMetric_2(metrics.isMetric_2) if (sales.metrics.isMetric_3) acc.metrics.setIsMetric_3(metrics.isMetric_3) acc }
猜你喜欢
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多