0

私は今Scalaを学んでいて、ある要素(たとえばnum)をリスト内のすべての要素と比較しなければならないシナリオがあります。

推定、

val MyList = List(1, 2, 3, 4)

numリスト内の要素が誰とでも等しい場合は、を返す必要がありtrueます。headand関数を使用して再帰的に実行することは知っていますtailが、もっと簡単な方法はありますか(を使用して実行できると思いますがforeach、正確に実装する方法がわかりません)。

4

4 に答える 4

10

いくつかの可能性があります:

val x = 3
MyList.contains(x)
!MyList.forall(y => y != x) // early exit, basically the same as .contains

頻繁に行う予定がある場合は、リストをセットに変換することを検討してください。.contains最悪の場合、リストのすべてのルックアップは要素の数に比例しますが、セットでは効果的に一定です

val mySet = MyList.toSet
mySet.contains(x)

または単に:

mySet(x)
于 2012-10-08T11:15:12.803 に答える
3

メソッドは、どの言語のcontainsリストでも非常に標準的です。ScalaListにもそれがあります:

http://www.scala-lang.org/api/current/scala/collection/immutable/List.html

于 2012-10-08T11:13:26.037 に答える
3

他の人が答えたcontainsように、リストの方法はまさにこれを行い、最も理解しやすく/パフォーマンスの高い方法です。

ただし、締めくくりのコメントを見ると、が返されるため、 で(エレガントな方法で)それを行うことはできません。Foreach は各要素に対して何かを「実行」しますが、結果は返されません。これは logging/println ステートメントに役立ちますが、変換としては機能しません。foreachUnit

すべての要素に対して個別に関数を実行する場合はmap、関数を適用した結果のリストを返す を使用します。したがって、num = 3 と仮定すると、MyList.map(_ == num)が返されList(false, false, true, false)ます。結果のリストではなく単一の結果を探しているので、これはあなたが求めているものではありません。

一連のものを 1 つの結果にまとめるには、データを折りたたむ必要があります。折りたたみには、2 つの引数 (これまでの結果とリスト内の現在のもの) を取り、新しい実行結果を返す関数が含まれます。これが最初の要素で機能するように、進行中の結果に使用する初期値 (通常は何らかのゼロ) も提供する必要があります。

あなたの特定のケースではBoolean、最後に答えが必要です-「見つかった要素は「と等しいnum」でした。したがって、実行結果は「これまでに次の要素を見たことがありますか」となりますnum。つまり、初期値はfalseです。trueまた、要素が既に表示されている場合、または現在の要素が と等しい場合、関数自体が返されnumます。

これをまとめると、次のようになります。

MyList.foldLeft(false) { case (runningResult, listElem) =>
   // return true if runningResult is true, or if listElem is the target number
   runningResult || listElem == num
}

これには、ターゲット値が見つかったらすぐに停止するという優れた側面はありません。また、 を呼び出すほど簡潔ではありませんMyList.contains。しかし、教育的な例として、これはリストの基本的な機能操作からこれを自分で実装する方法です。

于 2012-10-08T11:39:42.820 に答える
2

Listそのための方法があります:

val found = MyList.contains(num)
于 2012-10-08T11:13:19.480 に答える