Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala return boolean with if else

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?

like image 759
bajro Avatar asked Dec 12 '15 15:12

bajro


3 Answers

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
  }
like image 75
vvg Avatar answered Oct 25 '22 22:10

vvg


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
}
like image 26
Kigyo Avatar answered Oct 25 '22 23:10

Kigyo


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.

like image 10
Ende Neu Avatar answered Oct 25 '22 21:10

Ende Neu