私は今Scalaを学んでいて、ある要素(たとえばnum
)をリスト内のすべての要素と比較しなければならないシナリオがあります。
推定、
val MyList = List(1, 2, 3, 4)
num
リスト内の要素が誰とでも等しい場合は、を返す必要がありtrue
ます。head
and関数を使用して再帰的に実行することは知っていますtail
が、もっと簡単な方法はありますか(を使用して実行できると思いますがforeach
、正確に実装する方法がわかりません)。
私は今Scalaを学んでいて、ある要素(たとえばnum
)をリスト内のすべての要素と比較しなければならないシナリオがあります。
推定、
val MyList = List(1, 2, 3, 4)
num
リスト内の要素が誰とでも等しい場合は、を返す必要がありtrue
ます。head
and関数を使用して再帰的に実行することは知っていますtail
が、もっと簡単な方法はありますか(を使用して実行できると思いますがforeach
、正確に実装する方法がわかりません)。
いくつかの可能性があります:
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)
メソッドは、どの言語のcontains
リストでも非常に標準的です。ScalaList
にもそれがあります:
http://www.scala-lang.org/api/current/scala/collection/immutable/List.html
他の人が答えたcontains
ように、リストの方法はまさにこれを行い、最も理解しやすく/パフォーマンスの高い方法です。
ただし、締めくくりのコメントを見ると、が返されるため、 で(エレガントな方法で)それを行うことはできません。Foreach は各要素に対して何かを「実行」しますが、結果は返されません。これは logging/println ステートメントに役立ちますが、変換としては機能しません。foreach
Unit
すべての要素に対して個別に関数を実行する場合は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
。しかし、教育的な例として、これはリストの基本的な機能操作からこれを自分で実装する方法です。
List
そのための方法があります:
val found = MyList.contains(num)