I have a CriteriaBuilder-based query that can be ordered by several different properties.
Currently it's being handled somehow like this:
when(filters.sortBy) {
"foo" -> query.orderBy(if(isAsc) cb.asc("bar") else cb.desc("bar"))
"baz" -> query.orderBy(if(isAsc) cb.asc("quux") else cb.desc("quux"))
}
It's definitely not the most readable or maintainable code I've ever written.
Is there a better and possibly more idiomatic way to do this in Kotlin, given that it doesn't have the ternary ? : operator?
Note that some of the properties I need to order by may be subproperties of the root object, so just extracting this to a method that takes a string as the name of the order clause may not be easy.
when is an expression, so you can use it's result directly as an argument in query.orderBy()
Also, local function would help to eliminate if-else duplication part
fun query(...) {
...
fun sort(name: String) = if (isAsc) cb.asc(name) else cb.desc(name)
query.orderBy(sort(
when (filters.sortBy) {
"foo" -> "bar"
"baz" -> "quux"
}
))
...
}
Related
In Rescript, one can define a Record in this format:
type record1 = {
a : String
}
but NOT:
type record2 = {
[a] : String
}
I am looking to write a record that compiles to JS like:
{
[Op.or]: [12,13]
}
The use case above comes from Sequelize, and the reference is here.
My current solution:
%raw(`{[Op.or]:[12,13]}`)
It's not entirely clear how you intend to interface with the Op construct, whether you can bind to it or not, but here's an example that does, and along with Js.Dict.t effectively produces the same output:
module Op = {
#val external or: string = "Op.or"
}
Js.Dict.fromList(list{
(Op.or, [12, 23])
})
It does not directly compile to the JS you want, however, which might be a problem if you rely on something that actually parses the source code. But short of that, I believe this should do what you ask for.
I have to return true or false based on field value in inner set item. My loops is as follow
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) true
})
})
false
It shoudld break and return true as soon as I have true on available but its returning false all the time. Any suggestion?
I don't have your dataset to work with, but perhaps this might do it.
myChoice.category.exists(_.flavours.exists(_.available))
Scala doesn't have continue or break. Because it is a fully functional language, every expression (including a loop) must have a value. Moreover, it tries to break out of the imperative style of initializing variables and mutating them over the course of a loop. Instead, scala encourages you to use a functional style, i.e. use methods that apply to data structures as a whole to transform/search for the desired result.
For your case, you're clearly looking to see if any of the flavors have their available field set to true. Thus you could flatMap the whole nested collection to a List of Boolean, and take the or of the whole collection:
val anyAvaliable = myChoice.category.flatMap(a => a.flavours).reduce( (flavour1,flavour2) => flavour1.available || flavour2.available)
jwvh's solution is even more concise. There are many ways of accomplishing essentially the same thing. Don't fight the language, have it fight for you!
Disclaimer: the below solution is provided for completeness, but jwvh's answer should be preferred for this case and generally speaking there are better alternatives. In particular, note that return from inside a lambda is implemented using exceptions, so 1) it may perform much worse than normal method calls; 2) if you are careless you can accidentally catch it.
If this is the last thing you need to do in the method, you can just use return:
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) return true
})
})
false
If it isn't, you can extract a method (including a local one):
def foo = {
...
val myChoice = ...
def hasAvailableFlavorsMethod() = {
myChoice.category.foreach(category => {
category.flavours.foreach(flavour=> {
if (flavour.available) return true
})
})
false
}
val hasAvailableFlavors = hasAvailableFlavorsMethod()
...
}
In my scala code:
QueueManager.add(getObject)
where getObject is a method that returns an object of type QueueObject.
def getObject : QueuObject = {
val response = //some response
return response
}
Is there a way I can check for the response being null, while adding the QueueObject? I know I can do this:
if (getObject != null)
QueueManager.add(getObject)
But I do not wish to add a level of indentation. Is there an operator that does that inline?
Thanks.
Try to avoid using null in Scala. It's really there only for interoperability with Java. In Scala, use Option for things that might be empty. If you're calling a Java API method that might return null, wrap it in an Option immediately.
def getObject : Option[QueueObject] = {
// Wrap the Java result in an Option (this will become a Some or a None)
Option(someJavaObject.getResponse)
}
Note: You don't need to put it in a val or use an explicit
return statement in Scala; the result will be the value of
the last expression in the block (in fact, since there's only one statement, you don't even need a block).
def getObject : Option[QueueObject] = Option(someJavaObject.getResponse)
Besides what the others have already shown (for example calling foreach on the Option, which might be slightly confusing), you could also call map on it (and ignore the result of the map operation if you don't need it):
getObject map QueueManager.add
This will do nothing if the Option is a None, and call QueueManager.add if it is a Some.
I find using a regular if however clearer and simpler than using any of these "tricks" just to avoid an indentation level. You could also just write it on one line:
if (getObject.isDefined) QueueManager.add(getObject.get)
or, if you want to deal with null instead of using Option:
if (getObject != null) QueueManager.add(getObject)
edit - Ben is right, be careful to not call getObject more than once if it has side-effects; better write it like this:
val result = getObject
if (result.isDefined) QueueManager.add(result.get)
or:
val result = getObject
if (result != null) QueueManager.add(result)
Option(getObject) foreach (QueueManager add)
If it instead returned Option[QueueObject] you could use a construct like getObject.foreach { QueueManager.add }. You can wrap it right inline with Option(getObject).foreach ... because Option[QueueObject](null) is None.
Although I'm sure #Ben Jackson's asnwer with Option(getObject).foreach is the preferred way of doing it, I like to use an AnyRef pimp that allows me to write:
getObject ifNotNull ( QueueManager.add(_) )
I find it reads better.
And, in a more general way, I sometimes write
val returnVal = getObject ifNotNull { obj =>
returnSomethingFrom(obj)
} otherwise {
returnSomethingElse
}
... replacing ifNotNull with ifSome if I'm dealing with an Option. I find it clearer than first wrapping in an option and then pattern-matching it.
(For the implementation, see Implementing ifTrue, ifFalse, ifSome, ifNone, etc. in Scala to avoid if(...) and simple pattern matching and the Otherwise0/Otherwise1 classes.)
There are a number of times I've run into a simple pattern when programming in Java or C++ for which a custom control structure could reduce the boilerplate within my code. It goes something like:
if( Predicate ){
Action
return Value
}
that is, a "return if"-type statement. I've tried making functions with signature like foo[A,B]( pred:((A,A)=>Boolean), value:Option[B] ) but then I wind up checking if I've returned Some or None. I'm tripped up by the return statement.
Is there an inherit way of making such control structures in functional languages or more specifically Scala?
Edit:
I was not as clear with my description and it's confusing people who are trying to help me. The key reason my foo doesn't work is that it can't short-circuit the evaluation of the containing function. That is
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
return_if( withinBounds( geometry, projection ), logToString( logger, "Geometry outside " + projection.toString ), EmptyGeometry() )
return_if( topologicallyCorrect( geometry ), intersect( correct( geometry ), reference )
//rest of the function
}
and still allow for tail recursion within the return_if.
I would use a partial function:
def whatevs[A, B](options : PartialFunction[(A,A), B]) : Option[B] = {
val myInput = generateInput
if(options.isDefined(myInput)) {
Some(options(myInput))
} else None
}
Then your usage could look like the following:
whateves {
case (x,y) if x > y => "Biggerz"
case (x,y) if y > x => "Tiny!"
}
In general, you do not need a return statement. If-expression will evaluate to the last expression used in each block. You may need to help the compiler figure out the type-result of the if expression, but the return is unneeded.
Partial Functions are a mechanism to perform an action if some condition holds true. In the above, the two conditions are x > y or y > x from the tuple.
If the whatevs function is not quite what you're talking about I'd recommend using raw pattern matching.
Hmm, as far as I understand it you want the return in the control structure to exit the function it is embedded in.
So in your example it should exit the method intersect?
I am not sure if thats possible. Because a return inside the return_if will always exit return_if and I don't think there is a way to tell scala, that the return should exit the function return_if is embedded in.
I hope I understood what you wanted to do :)
It looks like you're using this as a conditional escape from the control flow of the code.
You can do this in Scala too (just annotate the method with the type to return) if it's really the most elegant solution to the problem. Sometimes code needs to act like a multi-stage filter, and this pattern works well for that.
Of course you can always nest if-statements, but that gets awkward.
There are a couple of other things to consider in Scala, however. One can
methodReturningOption.getOrElse(
// All the code for the None case goes in here
)
which usually works pretty well at consolidating different branches in the case that there is a sensible default (or you'll end up throwing an exception if there's not).
Alternatively, you can abuse pattern matching for this:
None match { // Could use a real variable instead of None if it helped
case _ if (Predicate1) => Action1; Value1
case _ if (Predicate2) => Action2; Value2
. . .
case _ => ErrorHandlingPerhaps
}
But you also might be able to think about your problem in a different way so that these sort of predicates become less useful. (Without knowing more details, I can't suggest something.)
I am at a loss to understand why you would want this. Here's the code you want to write:
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
return_if( withinBounds( geometry, projection ),
logToString( logger, "Geometry outside " + projection.toString ),
EmptyGeometry() )
return_if( topologicallyCorrect( geometry ),
intersect( correct( geometry )),
reference )
// rest of the function
}
while here's what it looks like in "ordinary" Scala:
def intersect( geometry:Geometry, reference:Geometry ):Geometry = {
if (withinBounds( geometry, projection )) {
logToString( logger, "Geometry outside " + projection.toString )
return EmptyGeometry() }
if( topologicallyCorrect( geometry )) {
intersect( correct( geometry ))
return reference }
//rest of the function
}
To me the "ordinary" version looks a lot clearer. For one thing it makes it very clear what is being returned. It's not even more verbose. I suspect you have a more complex use case. If you show us that, maybe we will be able to direct you to patterns that are more appropriate.
I'm trying to write a class for a scala project and I get this error in multiple places with keywords such as class, def, while.
It happens in places like this:
var continue = true
while (continue) {
[..]
}
And I'm sure the error is not there since when I isolate that code in another class it doesn't give me any error.
Could you please give me a rule of thumb for such errors? Where should I find them? are there some common syntactic errors elsewhere when this happens?
It sounds like you're using reserved keywords as variable names. "Continue", for instance, is a Java keyword.
You probably don't have parentheses or braces matched somewhere, and the compiler can't tell until it hits a structure that looks like the one you showed.
The other possibility is that Scala sometimes has trouble distinguishing between the end of a statement with a new one on the next line, and a multi-line statement. In that case, just drop the ; at the end of the first line and see if the compiler's happy. (This doesn't seem like it fits your case, as Scala should be able to tell that nothing should come after true, and that you're done assigning a variable.)
Can you let us know what this code is inside? Scala expects "expressions" i.e. things that resolve to a particular value/type. In the case of "var continue = true", this does not evaluate to a value, so it cannot be at the end of an expression (i.e. inside an if-expression or match-expression or function block).
i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
}
This is a problem, as the function block is an expression and needs to have an (ignored?) return value, i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
()
}
() => a value representing the "Unit" type.
I get this error when I forget to put an = sign after a function definition:
def function(val: String):Boolean {
// Some stuff
}