Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have this method that I need to evaluate an expression based on these Boolean values:

var Ma, Co, Ar, Le, St, Ri: Boolean = false
def Logic: Boolean =
  (Ma  &  (!Ma  |  Co)  &  (!Ma  |  Ar)  &  (!Co  |  Ma)  &  
      (!Ar  |  Ma)  &  (!Ar  |  Le  |  St |  Ri))

In main() method I have:

def main(args: Array[String]) {   
  val ls: List[String] = List("Ma", "Co", "Ar")
  //now I need to change the value of Ma, Co and Ar variables to "true"??
}

Is there a general way that may help to change the value of only these Boolean variables to true that are found in this list?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

Not without reflection, I think. But if you keep the name->value mapping in a map, you can do something like this:

val v =  scala.collection.mutable.Map[String, Boolean]("Ma" -> false, "Co"-> false, "Ar" -> false, "Le" -> false, "St" -> false, "Ri" -> false)
    //> v  : scala.collection.mutable.Map[String,Boolean] = Map(Ar -> false, Le -> f
    //| alse, Co -> false, Ma -> false, St -> false, Ri -> false)
def Logic:Boolean = (v("Ma")  &  (!v("Ma")  | v("Co"))  &  (!v("Ma")  |  v("Ar"))  &  (!v("Co")  | v("Ma"))  &
        (!v("Ar")  |  v("Ma"))  &  (!v("Ar")  |  v("Le")  |  v("St") |  v("Ri")))
    //> Logic: => Boolean

val ls: List[String] = List("Ma", "Co", "Ar")     //> ls  : List[String] = List(Ma, Co, Ar)
v("Ma")                                           //> res0: Boolean = false
ls.foreach(v(_) = true)
v("Ma")                                           //> res1: Boolean = true
Logic                                             //> res2: Boolean = false
share|improve this answer
    
I am already using your suggestion, and @Ashalynd 's one. They look functional, but I have to understand now what v(..) means and I didn't know when to use it :( –  Heva Jul 21 at 12:01
    
v is just a Map, and holds String keys and corresponding Boolean valuer. v(foo) is shorthand for v.apply(foo), and takes the String foo, looks up the corresponding value, and returns it @Ashalynd's solution extends this idea to have a Map with a default value of false so you only have to set specific names to true. Although convenient, I don't like this as it means if you misspell a parameter name, it will return false when you look it up, which may be difficult to track down. In my version, using an unknown name would be a (runtime) error –  Paul Jul 21 at 12:02

You can use an Enumeration, and use its ValueSet to store your true values instead of individual vars. This lets you refer to them by String name:

object MyBoolValue extends Enumeration {
  type MyBoolValue = Value
  val Ma, Co, Ar, Le, St, Ri = Value
}
class MyBoolValueContext {
  var trueValues = MyBoolValue.ValueSet.empty
  def isTrue(v: MyBoolValue) = trueValues contains v
  def apply(v: MyBoolValue) = isTrue(v)
}

So then you can do:

import MyBoolValue._
val c = new MyBoolValueContext
c(Ma)
c.trueValues += Le
c.trueValues -= St

def logic: Boolean = (c(Ma) &
                      (!c(Ma) | c(Co)) &
                      (!c(Ma) | c(Ar)) &
                      (!c(Co) | c(Ma)) &
                      (!c(Ar) | c(Ma)) &
                      (!c(Ar) | c(Le) | c(St) | c(Ri)))

And you can use withName to handle String input:

c.trueValues ++= List("Ar", "Le", "St").map(MyBoolValue.withName)

You can get a little fancier by making the context implicit:

implicit case class ResolveMyBoolValue(self: MyBoolValue) extends AnyVal {
  def get(implicit context: MyBoolValueContext): Boolean = context.isTrue(self)
}

implicit val context = new MyBoolValueContext

val result = Ar.get | !St.get

Or use an implicit conversion, though this could cause some confusion if misused:

implicit def resolveMyBoolValue(v: MyBoolValue)
                               (implicit context: MyBoolValueContext) = {
  context.isTrue(v)
}

val result: Boolean = Le
share|improve this answer
    
I personally think this one's a bit overkill, but it's neat, so +1 anyway. It seems to be coming fairly close to implementing your own Boolean type (or "set of Booleans" type) –  Paul Jul 21 at 13:26
    
I really appreciate your reply @Dan Getz...but for me, as a kind of beginner in Scala, this is of a "heavy caliber":) –  Heva Jul 21 at 22:02

One of the ways to do it:

def Logic(params:List[String]) = {
 val p = params.map(par => (par, true)).toMap.withDefaultValue(false)
 (
    p("Ma")  &  (
        !p("Ma")  |  p("Co")
    )  &  (
        !p("Ma")  |  p("Ar")
    )  &  (
        !p("Co")  |  p("Ma")
    )  & (
        !p("Ar")  |  p("Ma")
    )  &  (
        !p("Ar")  |  p("Le")  |  p("St") |  p("Ri")
    )
  )
}

scala> Logic(List("Ma","Co","Ar"))
res0: Boolean = false
scala> Logic(List("Ma","Co","Ar","Le"))
res1: Boolean = true
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.