您如何遍历scala中的每个状态?

时间:2018-12-06 20:13:24

标签: java scala testing apiclient

我正在尝试遍历每个状态,以检查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.get(x)的单个项。

3 个答案:

答案 0 :(得分:1)

干净的方法是

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

或更短

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

val inactive类似。这确实存在遍历列表两次的问题(但是,与代码不同,两次都找到了合适的项目就停止了)。

答案 1 :(得分:1)

对于“至少1个”,您可以在exists上使用items来检查给定的谓词,如果其中至少一项满足条件,则返回true。对于“ ACTIVE和INACTIVE”,您可以使用&&将两个exists调用组合为效率低下的方法。

reasons.items.exists(_.status.equals("ACTIVE")) && reasons.items.exists(_.status.equals("INACTIVE"))`

答案 2 :(得分: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语法以添加对activeinactive的支持:

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)

在这里的示例中,定义您自己的匹配器只是为了在断言中保存几个单词,这看起来有些愚蠢,但是如果您编写了数百个关于相同属性的测试,那么将断言放下来真的很方便一行,并且自然可读。因此,以我的经验,如果您在很多测试中重复使用它们,那么定义自己的匹配器就很有意义。