Reputation: 1250
So I have to following scenario:
def check(): Boolean = {
for ((digit1,digit2,digit3) <- SetOfDigits){
if ((1,2,5) == (digit1,digit2,digit3))
true
else
false
}
}
val SetOfDigits = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5))
Now the problem is that the function has to return a Boolean but it always tells me that the return type here is Unit
?
The function should iterate over the SetOfDigits
and if it finds something equal like (1,2,5)
it should return true else false?
Has anybody an answer to this problem and what I have to do in order to get it working?
Upvotes: 10
Views: 37251
Reputation: 15783
I don't agree with the solution from Mr. V., I'd rather suggest you change your implementation, that seems a very Javish way of handling things:
scala> val SetOfDigits = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5))
SetOfDigits: scala.collection.immutable.Set[(Int, Int, Int)] = Set((0,2,3), (1,5,6), (7,10,2), (1,2,5))
scala> SetOfDigits.contains((1, 2, 5))
res0: Boolean = true
scala> SetOfDigits.contains((1, 2, 4))
res1: Boolean = false
contains
find an element in your set, if the element is not there, it returns false, looks much better in my opinion.
In response to your comment, I'd flatten the first list and then use forAll
and contains
:
scala> val setOfDigits1 = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5)).flatMap { case(a,b,c) => Set(a,b,c)}
setOfDigits1: scala.collection.immutable.Set[Int] = Set(0, 5, 10, 1, 6, 2, 7, 3)
scala> val setOfDigits2 = Set(1,2,3,16,20,7)
setOfDigits2: scala.collection.immutable.Set[Int] = Set(20, 1, 2, 7, 3, 16)
scala> val setOfDigits3 = Set(1,2,3,10)
setOfDigits3: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 10)
scala> setOfDigits2.forall(i => setOfDigits1.contains(i))
res8: Boolean = false
scala> setOfDigits3.forall(i => setOfDigits1.contains(i))
res9: Boolean = true
Note that I have flattend the first list from a List[(Int, Int, Int)]
to a List[Int]
, then forAll
evaluates a predicate which must be true for all elements and contains
does the rest.
Upvotes: 10
Reputation: 5768
I agree with Ende Neu's answer.
In the general case you can introduce a boolean variable that you check inside the for-comprehension to end it prematurely. I prefer it over using the return
keyword.
def check(): Boolean = {
var found = false
for ((digit1,digit2,digit3) <- SetOfDigits if !found) {
if ((1,2,5) == (digit1,digit2,digit3)) found = true
}
found
}
Upvotes: 3
Reputation: 20435
As mentioned, yield the result from the if-else
, otherwise the for comprehension returns Unit
. In a similar way to @EndeNeu API based method, consider also
xs.exists( _ == (1,2,5) )
Boolean = true
which halts the iteration over the collection as the first match is found.
Note also by convention the tag of a collection starts with a lower case letter, namely setOfDigits
instead of SetOfDigits
, while types and classes are capitalised.
Upvotes: 2
Reputation: 6395
You should add return
statement before true or false
to stop on first execution.
Otherwise you can use yield
to collect results from each of sub-set (you'll get list of Booleans)
Depends what is your expectation. If you want to make sure at least on of sub-sets satisfying results, your function will looks like following:
def check(): Boolean = {
val s = for ((digit1,digit2,digit3) <- SetOfDigits) {
if ((1,2,5) == (digit1,digit2,digit3))
return true
}
false
}
Upvotes: 7