Remove elements in a string separated by commas in groovy - string

I am building a string in this way:
def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"
What happens is that sometimes the variables has null values, and the resulting string is showing this null values, I have to avoid show null values.
I want to know if there is some way to remove this possible null values in the string or avoid add this when they will be presented.
I know that it is possible and more easy to do with arrays, but I want to do it with strings in a more direct way.
Thanks for any help in advance.

There are 3 options:
1. GString interpolation
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
2. Using StringBuilder
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
3. Joining a list with , as a delimiter
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
Benchmark
Before going into conclusion let's benchmark all 3 methods using GBench tool:
#Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
def feedDisplayType = 'test'
def moduleType = null
def cellType = ''
def r = benchmark {
'GString method' {
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
}
'StringBuilder method' {
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
}
'Join list method' {
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
}
}
r.prettyPrint()
Output
Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
* JRE: 1.8.0_171
* Total Memory: 236 MB
* Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
GString method 265 2 267 268
StringBuilder method 72 4 76 77
Join list method 484 3 487 495
Conclusion
If you aim towards highest throughput, StringBuilder method is the best one (77 nanoseconds mean time).
GString method is a few times slower than StringBuilder and it is much less readable due to all condition statements inside a single GString. It is also pretty error prone - it's easy to make a mistake when interpolating String in this case.
Joining list method is the slowest one (only 2 times slower approximately than GString method), but it is the cleanest one. And it is still pretty fast - 495 nanoseconds is acceptable in most cases. Of course optimization depends on specific use case - if you have to execute this part of code million times per second, then using StringBuilder instead makes much more sense.
Benchmark corner cases
To make this example complete let's also take a look at corner cases in benchmarking. We use the same code with different input.
Input:
def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'
Output:
user system cpu real
GString method 387 1 388 390
StringBuilder method 170 0 170 175
Join list method 847 6 853 859
Input:
def feedDisplayType = ''
def moduleType = ''
def cellType = ''
Output:
user system cpu real
GString method 237 5 242 242
StringBuilder method 44 0 44 44
Join list method 441 0 441 446

Edit: This answer has been changed as there is a requirement to not print "," for null terms.
Consider:
def feedDisplayType = 'abc'
def moduleType = null
def cellType = 'ijk'
def f = { s, isLast = false ->
def token = s ?: ''
def seperator = (!s || isLast) ? '' : ','
"${token}${seperator}"
}
def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
assert 'abc,ijk' == presentationType
Note that in function calls, parens are optional in Groovy so ${f x} is equivalent to ${f(x)}. f was originally field in an earlier version, but I've shortened it for brevity.

Related

In Groovy -How to fill empty fields in version with number zero?

I have a version like below and I want to add zero (0) in versionB after 2 decimal. How can I achieve this in groovy?
versionA=1.12.14
versionB=1.11
Expected OutPut:-
versionA=1.12.14
VersionB=1.11.0
Solution
The term you are are looking for is Semantic Versioning ( semver ). This is not the prettiest solution but it will work
//def semver = "1"
def semver = "1.13"
def split = semver.split("\\.");
if(split.size() == 1) {
semver+=".0.0"
} else if(split.size()==2) {
semver+=".0"
}
println semver
In your example you have the variables typed as numbers but they must be strings
A generic variant for version strings of variable lengths:
String getFormattedVersion( String raw, int maxPositions = 3 ){
def parts = raw.split( /\./ )
(0..<maxPositions).collect{ it < parts.size() ? parts[ it ] : '0' }.join '.'
}
assert '1.2.3' == getFormattedVersion( '1.2.3' )
assert '1.2.0' == getFormattedVersion( '1.2' )
assert '1.0.0' == getFormattedVersion( '1' )
assert '1.2.3.0.0' == getFormattedVersion( '1.2.3', 5 )

Groovy : Can I use assert in conjuction with elvis operator?

I would like to increment the values based on assert results :
def a = 1
def b = 1
def c = 0
def d = 0
(assert a==b, "Mismatch") ? (c++) : (d++)
Is it possible?
You misunderstood one important part - assert is not a function and it does not return any value. It is a Groovy's (and Java) keyword (statement) that throws an exception if the expression on the right side evaluates to false, but it does not return any result. However, you can achieve expected result using ternary operator in the way it was designed to use:
def a = 1
def b = 1
def c = 0
def d = 0
a == b ? (c++) : (d++)
println "c = ${c}, d = ${d}"
Output:
c = 1, d = 0
You can read more about using assertions in Groovy's official "Testing Guide, chapter 2.1 Power Assertions".
If you really want to "ignore" the assert and continue, you can catch the exception it throws. E.g.
def a = 1
def b = 1
def c = 0
def d = 0
try {
assert a==b, 'Mismatch'
c++
}
catch (AssertionError e) {
d++
}
println([a,b,c,d])
I'd only use tactics like that, if some foreign code dictates that on me. This is very convoluted code unless you want to abuse the power-assert to generate a nice "warning" log message for you.

How to get last 2 digit from a String

I have a problem to get last two digit from a string.
example :
String texter = "5793231309"
how to get '09' ?
so when Iprintln "texter : "+texter.
It will be Groovy<<09
I try split but it not successful ?
Use this to split your first String:
static main(args) {
String texter = "5793231309"
String texter2 = texter[-2..-1]
println(texter2)
}
Here's a one liner that's also a safe alternative:
assert "5793231309".reverse().take(2).reverse() == "09"
In groovy you can substring via negative indices.
String last2 = texter[-2..-1] // Last 2 symbols
Its an analogue of substring, and it uses Ranges.
http://groovy.codehaus.org/Collections see 'Slicing with the subscript operator'
Inspired by tim_yates:
It may be safer to use some function, to extract last n characters, as tim suggested. But I think his solution, with regexp is a big overhead, and may be hard to understand by novices.
There is an easier and faster way to do this, using size() check, and then range substring:
def lastN(String input, int n){
return n > input?.size() ? null : n ? input[-n..-1] : ''
}
assert lastN("Hello", 2) == 'lo'
assert lastN("Hello", 3) == 'llo'
assert lastN("Hello", 0) == ''
assert lastN("Hello", 13) == null
assert lastN(null, 3) == null
Be careful though, if your unit is less than 2 characters long, s[ -2..-1 ] will fail.
Might be better to do:
String lastN( String input, int n ) {
input == null ?
null :
( input =~ /^.+(\S{$n})$/ ).with { m -> m.matches() ?
m[ 0 ][ 1 ] :
null }
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
Or:
String lastN( String input, int n ) {
if( input == null || input.length() < n ) null
else if( n == 0 ) ''
else input[ -n..-1 ]
}
assert lastN( "5793231309", 2 ) == '09'
assert lastN( "5793231309", 3 ) == '309'
assert lastN( "5793231309", 0 ) == ''
assert lastN( '', 2 ) == null
assert lastN( null, 2 ) == null
The most readable solution is probably just to drop() all but the last two characters:
def texter = "5793231309"
println texter.drop(texter.size() - 2) //result: "09"
Or as a reusable closure:
def lastTwo = { it.drop(it.size() - 2) }
println lastTwo("ABC") //result: "BC"
println lastTwo("AB") //result: "AB"
println lastTwo("A") //result: "A" (no exception thrown)
println lastTwo("") //result: "" (no exception thrown)
Fiddle with the code:
https://groovyconsole.appspot.com/script/5768158526832640
More examples of Groovy goodness:
http://mrhaki.blogspot.com/2011/09/groovy-goodness-take-and-drop-items.html
Another safe alternative using size() and substring() methods:
s?.size() < 2 ? s : s.substring(s.size() - 2)
Note the above takes care of nulls and strings that are less than two characters long.
In Java use
String texter = "5793231309";
String val=texter.substring(texter.length()-2,texter.length());
System.out.println("val-->"+val);
In Groovy you don’t need the above stuff just,
String value= texter[-2..-1]

performance issues with groovy getProperty() method

suppose that i have a method which has the signature like
def myAction(objet,String propertyName);
i just want to retrieve the property value from objet, i wrote two versions
version 1: I construct the getter method and invoke it on objet
original = propertyName
prefix = original.substring(0,1).toUpperCase()
suffix = original.substring(1,original.length())
methodName = new StringBuilder('get').append(prefix).append(suffix).toString()
value = domain.metaClass.invokeMethod(objet,methodName,null)
version 2: I use directly getProperty method supplied by GroovyObject
value = objet.getProperty(propertyName)
Witch one has better performance?
thinks : )
We can test it to find out using GBench...
I came up with 4 different methods:
#Grab( 'org.gperfutils:gbench:0.4.2-groovy-2.1' )
// Your 'version 1' method
def method1( object, String propertyName ) {
original = propertyName
prefix = original.substring(0,1).toUpperCase()
suffix = original.substring(1,original.length())
methodName = new StringBuilder('get').append(prefix).append(suffix).toString()
assert 'tim' == object.metaClass.invokeMethod(object,methodName,null)
}
// Your 'version 2' method
def method2( object, String propertyName ) {
assert 'tim' == object.getProperty( propertyName )
}
// The same as method 1, but more Groovy
def method3( object, String propertyName ) {
assert 'tim' == object.metaClass.invokeMethod( object, "get${propertyName.capitalize()}",null)
}
// And get the property with the Groovy String templating
def method4( object, String propertyName ) {
assert 'tim' == object."$propertyName"
}
We can then define a class we're going to test:
class Test {
String name = 'tim'
}
def o = new Test()
And then we can run a benchmark over all 4 different versions:
benchmark {
'method1' {
method1( o, 'name' )
}
'method2' {
method2( o, 'name' )
}
'method3' {
method3( o, 'name' )
}
'method4' {
method4( o, 'name' )
}
}.prettyPrint()
On my machine, this prints out:
Environment
===========
* Groovy: 2.1.6
* JVM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01, Oracle Corporation)
* JRE: 1.7.0_25
* Total Memory: 255.125 MB
* Maximum Memory: 1095.125 MB
* OS: Mac OS X (10.8.4, x86_64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
method1 1630 7 1637 1648
method2 429 1 430 435
method3 1368 1 1369 1378
method4 629 1 630 637
So, the fastest is the getProperty one, followed by the object."$propertyName" one, followed by the shorter version of your version 1 method, followed by your original (and slowest) version 1 code
However, I'd argue that method4 is easier to read, and so you have to ask whether it is worth the slight dip in performance

Use of parametrized tests with void methods

I can't understand how I can setup a parametrized test with spock for void methods.
This is my simple test case for a linked list:
#Unroll
def "should delete the element #key and set the list size to #listSize"(key, listSize) {
given:
list.insert(6)
list.insert(12)
list.insert(33)
expect:
def deletedKey = list.delete(key)
list.size() == listSize
where:
key || listSize
6 || 2
12 || 2
33 || 2
99 || 3
}
The method delete() is a void method, but if I'm not getting explicitly a return value then the test is failing.
This is actually working:
expect:
def deletedKey = list.delete(key)
list.size() == listSize
while this doesn't:
expect:
list.delete(key)
list.size() == listSize
The test report complains about a null
Condition not satisfied:
list.delete(key)
| | |
| null 12
com.github.carlomicieli.dst.LinkedList#5c533a2
How can I manage this situation? I would like to test the results of deletion checking the list state after the deletion method has been called.
Thanks,
Carlo
Does it work if you use when and then rather than expect?
#Unroll
def "should delete the element #key and set the list size to #listSize"(key, listSize) {
given:
list.insert(6)
list.insert(12)
list.insert(33)
when:
list.delete(key)
then:
list.size() == listSize
where:
key || listSize
6 || 2
12 || 2
33 || 2
99 || 3
}

Resources