【问题标题】:Use forall instead of filter on List[A]在 List[A] 上使用 forall 而不是过滤器
【发布时间】:2012-10-20 17:52:10
【问题描述】:

正在尝试确定是否在每周比赛结果报告中显示加时赛显示标志。

数据库比赛结果表有 3 列 (p4,p5,p6),表示潜在的加时赛期间总得分(分别为加时赛、双加时赛和三倍加时赛)。这些列映射到应用层中的 Option[Int]。

目前我正在过滤游戏结果 teamA、teamB 对,但实际上我只是想知道是否存在任何类型的 OT 游戏(而不是逐步浏览集合)。

def overtimeDisplay(a: GameResult, b: GameResult) = {
  val isOT = !(List(a,b).filter(_.p4.isDefined).filter(_.p5.isDefined).filter(_.p6.isDefined).isEmpty)
  if(isOT) {
    <b class="b red">
    {List( ((a.p4,a.p5,a.p6),(b.p4,b.p5,b.p6)) ).zipWithIndex.map{
      case( ((Some(_),None,None), (Some(_),None,None)), i)=> "OT"
      case( ((Some(_),Some(_),None), (Some(_),Some(_),None )), i)=> "Double OT"
      case( ((Some(_),Some(_),Some(_)), (Some(_),Some(_),Some(_) )), i)=> "Triple OT"
    }}
    </b>
  }
  else scala.xml.NodeSeq.Empty
}

其次,确定显示哪种类型的加班,当前是繁忙的模式匹配(现在看来,它似乎并没有涵盖所有得分场景),可能可以以更实用/更简洁的方式完成。

如果您有更好的方法,请随时放下。

谢谢

【问题讨论】:

    标签: scala filter pattern-matching tuples forall


    【解决方案1】:

    不确定我是否正确理解了初始代码,但这是一个想法:

    val results = List(a, b).map(r => Seq(r.p4, r.p5, r.p6).flatten)
    val isOT = results.exists(_.nonEmpty)
    val labels = IndexedSeq("", "Double ", "Triple ")
    results.map(p => labels(p.size - 1) + "OT")
    

    将分数列转换为第一行的平面列表在这里至关重要。你有GameResult(p4: Option[Int], p5: Option[Int], p6: Option[Int]),你可以映射到Seq[Option[Int]]r =&gt; Seq(r.p4, r.p5, r.p6),然后展平以将Some[Int]转为Int并摆脱None。这会将Some(42), None, None 变成Seq(42)

    【讨论】:

    • +1 哇,更好的是,存在于 nonEmpty,awesome,并且,将模式匹配压缩到基本上没有,应该有一个 +10 选项;-)
    • @virtualeyes:我的错,改成:labels(p.size - 1)
    • 对,已经做到了,并且得到了一个索引越界异常。可能是我端的数据集,需要验证。还需要一个 if(isOT) ,否则每场比赛都显示为 OT,不是这种情况;-)
    • @virtualeyes: 对,p 的大小可以是03 之间的任何值,但如果你排除空(if(isOT)),一切都应该正常。很抱歉这个错误,正如我所说的,我没有完全理解这个域。
    • 不用担心,您已经完成的工作令人难以置信。我看到 List()、List(0)、List(1) 和 List(1,1) 作为 if(isOT) 的结果,所以数据集可能有问题(假设空 List 不应该在如果“results.exists(_.nonEmpty)”返回 true)
    【解决方案2】:

    看看这个:

    val isOT = !(List(a,b).filter(_.p4.isDefined).filter(_.p5.isDefined).filter(_.p6.isDefined).isEmpty)
    

    这可以使用exists 而不是filter 重写。我会重写如下:

    List(a, b).exists(x => x.p4.isDefined && x.p5.isDefined && x.p6.isDefined)
    

    除了使用exists,我还将您传递给过滤器的三个条件组合成一个匿名函数。

    此外,我不知道您为什么使用zipWithIndex,而之后您似乎没有在map 函数中使用索引。它可以完全删除。

    【讨论】:

    • +1,啊,存在,我明白了。回覆; zipWithIndex,是的,编译器抱怨在 List[Tuple3] 中传递的普通 zip,更容易在 zipWithIndex 上列出 [(Tuple3,Tuple3)]。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    • 2017-09-01
    • 1970-01-01
    相关资源
    最近更新 更多