Test only if variable is not null in if statement - groovy

I have the following method where I want to test the event.status property only if status has been passed in:
def findEvent(String desc, String status = null, Collection events) {
return events.find {
it.description == desc && \\If status is not null: it.status == status
}
throw new Exception("Review Event Record Not Found: ${desc}")
}
I thought it could be done like this, but it doesn't seem to work:
def findEvent(String desc, String status = null, Collection events) {
return events.find {
it.description == desc && (status != null ?: {it.status == status})
}
throw new Exception("Review Event Record Not Found: ${desc}")
}
Is there any way this could be done? Or do I have to go back to something like this:
if (status != null) {
return events.find {
it.description == desc && it.status == status
}
} else if (status == null) {
return events.find {
it.description == desc
}
}
Is there some kind of best practice?

I don't believe the expression is sensical as it is.
Elvis means "if truthy, use the value, else use this other thing."
Your "other thing" is a closure, and the value is status != null, neither of which would seem to be what you want. If status is null, Elvis says true. If it's not, you get an extra layer of closure.
Why can't you just use:
(it.description == desc) && ((status == null) || (it.status == status))
Even if that didn't work, all you need is the closure to return the appropriate value, right? There's no need to create two separate find calls, just use an intermediate variable.

Related

Combining nested conditional logical operators

I was wondering if any can help point me to resource to teach me more about logical operators, and answer a question for me. I would like (for the sake of satisfying my curiosity) to combine these nested conditional checks with logical operators into one statement.
if(obj1 != null && obj2 != null) {
if(obj1 != undefined && obj2 != undefined) {
//do something here
}
}
I have tried
if((obj1 != null || obj1 != undefined) && (obj2 != null || obj2 != undefined)) {
//do something here
}
But I don't think that works, since if obj1 or obj2 is equal to null or undefined than the or statement will evaluate to true. So the above code in the conditional would be executed if obj1 was null or undefined AND obj2 was null or undefined, which is definitely not what I want.
So how could I combine the nested conditional into one line?
Thanks!
:)
You might be overthinking. Code like
if (a) {
if (b) {
// stuff
}
}
executes stuff only if a and b are both true, so it is simply equivalent to
if (a && b) {
// stuff
}
Thus all you have to do is take your existing conditions and connect them with &&. You can write
if((obj1 != null && obj2 != null) && (obj1 != undefined && obj2 != undefined)) {
//do something here
}

Null and empty check in one go in groovy

Can someone please clarify below issue.
Below validation throw NULL pointer error when pass null in myVar. It is because of !myVar.isEmpty()
if (myVar!= null || !myVar.isEmpty() ) {
some code///
}
Below works though as expected,
if (myVar!= null) {
if (!myVar.isEmpty()) {
some code///
}
Any other way of having both steps together.
If .isEmpty() is used on a string, then you can also just use Groovy
"truth" directly, as null and also empty strings are "false".
[null, "", "ok"].each{
if (it) {
println it
}
}
// -> ok
if ( myVar!= null && !myVar.isEmpty() ) {
//some code
}
the same as
if ( !( myVar== null || myVar.isEmpty() ) ) {
//some code
}
and to make it shorter - it's better to add method like hasValues
then check could be like this:
if( myVar?.hasValues() ){
//code
}
and finally to make it groovier - create a method boolean asBoolean()
class MyClass{
String s=""
boolean isEmpty(){
return s==null || s.length()==0
}
boolean asBoolean(){
return !isEmpty()
}
}
def myVar = new MyClass(s:"abc")
//in this case your check could be veeery short
//the following means myVar!=null && myVar.asBoolean()==true
if(myVar) {
//code
}

OrientDB ClassCastException

I get the following exception when trying to access a relationship document:
java.lang.ClassCastException: com.orientechnologies.orient.core.id.ORecordId cannot be cast to com.orientechnologies.orient.core.record.impl.ODocument
via:
Collection<ODocument> field = myDoc.field("MY_FIELD_NAME");
if(field != null) {
return field;
} else {
return Collections.emptySet();
}
The strange thing is that is happes not always, most of the time it works like expected.
Depending by what the field contains, you could use the interface OIdentifiable instead of ODocument.
Try using:
Collection<OIdentifiable> field = myDoc.field("MY_FIELD_NAME");
if(field != null) {
return field;
} else {
return Collections.emptySet();
}

How to handle if no rows returned in Groovy

I have the following piece of code:
sql.eachRow(query){
def i=1
println("$i --> $it.columnName")
i++
}
If query returns some records(rows), there is no problem.
But if query is returning 0 records then how should I handle it. I want to show a user-friendly message, such as ZERO RECORDS FOUND.
def i=0
sql.eachRow(query) {
i++
println(i+" --> "+ it.columnName)
}
if (i == 0) {
println "ZERO RECORDS FOUND"
}
def rows = sql.rows(query)
if (rows.empty) {
// logic for handling no rows
} else if (rows.any { it.name == 'something' }) {
// logic for handling isExists == true
} else {
// logic for handling isExists == false
}
I'm not sure what's your specific case is, but it may be a case that checking name == 'something' condition can be done straight away at SQL level with WHERE name = 'something'. Then you could get rid off one of logical blocks in if statement.

Comparing pointers fails mystically in VC++

I have a tree structure and I want to find all nodes matching a given criteria. Each time I call the find function, it returns next matching node. Children are searched by recursive function call.
For some reason a key comparison of pointers fails for this implementation. Please see the code below, I have pointed out the failing comparison.
HtmlTag* HtmlContent::FindTag(string tagName, string tagParameterContent)
{
if (tagName.empty() && tagParameterContent.empty())
return NULL;
if (this->startTag == NULL)
return NULL;
this->findContinue = this->FindChildren(this->startTag, &tagName, &tagParameterContent);
return this->findContinue;
}
HtmlTag* HtmlContent::FindChildren(HtmlTag* firstTag, string* tagName, string* tagParameterContent)
{
HtmlTag* currentTag = firstTag;
HtmlTag* childrenFound = NULL;
while (currentTag != NULL)
{
if (!tagName->empty() && *tagName == currentTag->tagName)
{
if (tagParameterContent->empty() || currentTag->tagParameters.find(*tagParameterContent, 0) != -1)
{
if (this->findContinue == NULL)
break; // break now when found
else if (this->findContinue == currentTag) // TODO why this fails?
this->findContinue == NULL; // break on next find
}
}
if (currentTag->pFirstChild != NULL)
{
childrenFound = this->FindChildren(currentTag->pFirstChild, tagName, tagParameterContent);
if (childrenFound != NULL)
{
currentTag = childrenFound;
break;
}
}
currentTag = currentTag->pNextSibling;
}
return currentTag;
}
VC++ compiler accepts this code but for some reason I can't put a breakpoint on this comparison. I guess this is optimized out, but why? Why this comparison fails?
I think that you shoud replace == with = in assignment after comparison. Compiler optimalized this whole section because it doesnt do anything useful.

Resources