Как вы проходите через каждый статус в Scala? - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь перебрать каждое состояние, чтобы проверить, имеет ли ArrayList хотя бы 1 статус АКТИВНЫЙ и 1 НЕАКТИВНЫЙ.

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 содержит отдельные элементы, которые можно называть похожими по причинам.

Ответы [ 3 ]

0 голосов
/ 06 декабря 2018

Для "по крайней мере 1" вы можете использовать exists для items, который проверяет заданный предикат и возвращает истину, если хотя бы один из элементов удовлетворяет критериям.Для «ACTIVE и INACTIVE» вы можете объединить два exists вызова для неэффективного подхода, используя &&.

reasons.items.exists(_.status.equals("ACTIVE")) && reasons.items.exists(_.status.equals("INACTIVE"))`
0 голосов
/ 07 декабря 2018

Другие ответы хорошо объясняют, как этого добиться, используя коллекции 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, добавив поддержку active и 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)

В приведенных здесь примерах выглядит глупо определять собственные сопоставители, чтобы просто сохранить пару слов в утверждении, но если вы напишите сотни тестов с одинаковыми свойствами, это может быть очень удобнополучить ваши утверждения сводятся к одной строке и все еще будут естественно читаемыми.Таким образом, по моему опыту, определение таких собственных сопоставителей может иметь смысл, если вы повторно используете их во многих тестах.

0 голосов
/ 06 декабря 2018

Чистый подход будет

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

или короче

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

Аналогично для val inactive.Это имеет проблему повторения списка дважды (но остановка, как только подходящий элемент найден оба раза в отличие от вашего кода).

...