Reputation: 11
I have a big problem and I have several days trying to solve it, I hope someone can help me. The problem is the following: I have a list that can have n elements, but depending on the numbers of elements I should apply a function in different ways, as example I have the following code:
if (list.size() == 1){
p = list.get(0)
select = new Select(schema,p)
println(select)
} else { //If list have 2 elements
p = list.get(0)
p1 = list.get(1)
select = new Select(schema,And(p,p1))
println(select)
} else { //If list have 3 elements
p = list.get(0)
p1 = list.get(1)
p2 = list.get(2)
select = new Select(schema,new And(And(p,p1),p2))
println(select)
} else { //If list have 4 elements
p = list.get(0)
p1 = list.get(1)
p2 = list.get(2)
p3 = list.get(3)
select = new Select(schema,new And(And(p,p1),And(p2,p3))
println(select)
} else { //If list have 5 elements.......... and so on
How can avoid this sucesive conditionals and make that this work. I try with a for loop, but I can not generate new variables, and also I don't know how give a control to the And function.... If you need mor information please let me know
In order to add more information, the And function is a nested loop join that is use on relational databases:
sealed abstract class Pat //patterns
case class And( p1: Pat, p2: Pat) extends Pat
This have another functions that are using after I get the results of the conditionals described above. The idea also is that I can have n elements on the list, not a fix number, for that reason I think that a match is not an option
Upvotes: 0
Views: 113
Reputation: 3055
case class And(x:Any, y:Any)
def resolveAnd(lst: List[Int]):Any = {
if (lst.isEmpty) throw new Exception("Invalid list provided.")
lst.size match {
case 1 => lst.head
case _ => {
val size = if(lst.size%2==0)lst.size else lst.size+1
And(resolveAnd(lst.take(size/2)), resolveAnd(lst.drop(size/2)))
}
}
}
val list = 1::2::3::4::Nil
println(resolveAnd(list)) //output - And(And(1,2),And(3,4))
new Select(schema, resolveAnd(list))
Upvotes: 0
Reputation:
Assuming you want to build a tree hierarchy of And objects, you could use recursion to transform your list of Pat
objects into a binary tree of nested And
objects.
sealed abstract class Pat
case class Val(v: String) extends Pat
case class And(left: Pat, right: Pat) extends Pat
def buildParameterTree(xs: List[Pat]): Pat = {
xs match {
case p1 :: Nil => p1
case p1 :: p2 :: Nil => And(p1, p2)
case tail =>
val halves = tail.splitAt(tail.length/2)
And(buildParameterTree(halves._1), buildParameterTree(halves._2))
}
}
Usage:
scala> buildParameterTree(List("p1").map(Val))
res1: Pat = Val(p1)
scala> buildParameterTree(List("p1", "p2").map(Val))
res2: Pat = And(Val(p1),Val(p2))
scala> buildParameterTree(List("p1", "p2", "p3").map(Val))
res3: Pat = And(Val(p1),And(Val(p2),Val(p3)))
scala> buildParameterTree(List("p1", "p2", "p3", "p4").map(Val))
res4: Pat = And(And(Val(p1),Val(p2)),And(Val(p3),Val(p4)))
And so on...
For more information about the match statement and recursion in Scala see the respective links.
Upvotes: 1
Reputation: 51271
So you are wanting to And()
all the elements of the list? Would this work?
new Select(schema, list.reduce(And))
Upvotes: 1