0

我正在尝试遍历每个状态以检查 ArrayList 是否至少具有 1 个 ACTIVE 和 1 个 INACTIVE 状态。

var active = false;
var inactive = false;
for (item <- reasons.items) {
  if(item.status == "ACTIVE")
    active = true
  if(item.status == "INACTIVE")
    }
active must be (true)
inactive must be (true)

有没有更清洁的方法来做到这一点?我试过这样的流但没有运气

var active = false;      
var stream = reasons.items.toStream
        .forEach(item => if(item.status == "ACTIVE") {active = true})

注:原因包含项目(有 1 个项目)。items 包含可以调用的单个项目,如reasons.items.get(x)。

4

3 回答 3

1

干净的方法是

val active = reasons.items.exists(item => item.status == "ACTIVE")

或更短

val active = reasons.items.exists(_.status == "ACTIVE")

同样对于val inactive。这确实存在迭代列表两次的问题(但与您的代码不同,一旦两次都找到合适的项目就停止)。

于 2018-12-06T20:21:09.147 回答
1

对于“至少 1”,您可以使用existswhichitems检查给定的谓词,如果至少有一项满足条件,则返回 true。对于“ACTIVE 和 INACTIVE”,您可以exists使用 && 将两个调用组合起来以获得低效的方法。

reasons.items.exists(_.status.equals("ACTIVE")) && reasons.items.exists(_.status.equals("INACTIVE"))`
于 2018-12-06T20:25:44.043 回答
1

其他答案很好地解释了如何使用 Scala 集合来实现这一点。因为看起来您正在使用 ScalaTest,所以我想补充一点,您也可以使用 ScalaTest 循环遍历元素。

使用检查器的循环样式语法:

forAtLeast(1, reasons.items) { item =>
  item.status must be ("ACTIVE")
}

forAtLeast(1, reasons.items) { item =>
  item.status must be ("INACTIVE")
}

请注意,检查器与匹配器是分开定义的,因此您必须import org.scalatest.Inspectors._extends … with org.scalatest.Inspectors进入forAtLeast范围。

如果您想避免检查器的循环样式语法,可以将检查器简写语法与基于反射的语法一起使用have

atLeast(1, reasons.items) must have ('status "ACTIVE")
atLeast(1, reasons.items) must have ('status "INACTIVE")

如果您想避免基于反射的语法have,您可以扩展have语法以直接支持您的status属性:

def status(expectedValue: String) =
  new HavePropertyMatcher[Item, String] {
    def apply(item: Item) =
      HavePropertyMatchResult(
        item.status == expectedValue,
        "status",
        expectedValue,
        item.title
      )
  }

atLeast(1, reasons.items) must have (status "ACTIVE")
atLeast(1, reasons.items) must have (status "INACTIVE")

或者,如果您更喜欢be,则have可以扩展be语法以添加对activeand的支持inactive

class StatusMatcher(expectedValue: String) extends BeMatcher[Item] {
  def apply(left: Item) =
    MatchResult(
      left.status == expectedValue,
      left.toString + " did not have status " + expectedValue,
      left.toString + " had status " + expectedValue,
    )
}

val active = new StatusMatcher("ACTIVE")
val inactive = new statusMatcher("INACTIVE")

atLeast(1, reasons.items) must be (active)
atLeast(1, reasons.items) must be (inactive)

在此处的示例中,定义自己的匹配器只是为了在断言中保存几个单词看起来有点傻,但是如果您编写数百个关于相同属性的测试,将断言简化为一行会非常方便并且仍然是自然可读的。所以根据我的经验,如果你在很多测试中重用它们,像这样定义你自己的匹配器是有意义的。

于 2018-12-06T21:15:25.837 回答