Scala return boolean with if else

26,791

Solution 1

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.

Solution 2

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
  }

Solution 3

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
}

Solution 4

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.

Share:
26,791
bajro
Author by

bajro

Updated on December 13, 2020

Comments

  • bajro
    bajro over 3 years

    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?

  • bajro
    bajro over 8 years
    Okay that worked out now for me, but I got another question! Lets say my list SetOfDigits contains the tuples like yours above, and I want to compare another Set which contains: Set(1,2,3,16,20,7)... How can I yield true if all the digits which are in SetOfDigits appear once in the other Set, so only check for those which both contain and ignore the other ones?
  • Ende Neu
    Ende Neu over 8 years
    @Bajro I've made an edit, the answer was too long to fit a comment.
  • Luigi Plinge
    Luigi Plinge over 8 years
    It's just bad programming to go through the whole list when you should halt upon finding the required value. True, return isn't idiomatic Scala, but neither are mutable variables.