17

私は Scala に少し慣れていないので、これが少し些細なことである場合は申し訳ありません。

反復したいアイテムのリストがあります。各アイテムのチェックを実行し、そのうちの 1 つだけが失敗した場合は、関数全体が false を返すようにします。したがって、これは AND 条件と見なすことができます。つまり、最初の false に遭遇した瞬間に false を返します。

私はfor - yield、いくつかのジェネレーター (アイテムのリスト、シーケンスなど) によって生成されたアイテムをフィルター処理する構文に慣れています。ただし、私の場合は、残りのループを実行せずに、抜け出して false を返したいだけです。通常の Java ではreturn false;、ループ内で a を実行するだけです。

非効率的な方法 (つまり、最初の false アイテムに遭遇したときに停止しない) で、次のようにすることができます。

   (for {
          item <- items
          if !satisfiesCondition(item)
        } yield item).isEmpty

これは基本的に、フィルターを通過するアイテムがない場合、すべてのアイテムが条件を満たしていることを示しています。しかし、これは少し複雑で非効率的です (100 万個のアイテムがあり、最初のアイテムがすでに条件を満たしていないと考えてください)。

Scalaでこれを行うための最良かつ最もエレガントな方法は何ですか?

4

4 に答える 4

26

条件の最初の false で早期に停止するにはforall、Scala を使用します。(関連する質問)

あなたのソリューションは書き直されました:

items.forall(satisfiesCondition)

短絡を示すには:

List(1,2,3,4,5,6).forall { x => println(x); x < 3 }
1
2
3
res1: Boolean = false

の反対はforallexists条件が満たされるとすぐに停止することです。

List(1,2,3,4,5,6).exists{ x => println(x); x > 3 }
1
2
3
4
res2: Boolean = true
于 2013-11-14T15:54:56.000 に答える
2

forall特定のシナリオでは間違いなく最良の選択ですが、説明のために古き良き再帰を次に示します。

@tailrec def hasEven(xs: List[Int]): Boolean = xs match {
  case head :: tail if head % 2 == 0 => true
  case Nil  => false
  case _ => hasEven(xs.tail)
}

コレクションを含まない短絡のユースケースを伴うループには、再帰を頻繁に使用する傾向があります。

于 2013-11-15T03:05:56.323 に答える