Splitting a string using a delimiter in Groovy and avoiding IndexOutOfBoundsException
Solution 1
You can use Groovy's multiple assignment feature to safely grab 3 values from the second tokenization. Consider following example:
def inputDetails = "1234-a0-12;1111-b0-34"
def cDesc = inputDetails.tokenize(";")
cDesc.each { part ->
def (p1, p2, p3) = part.tokenize('-')
println "DEBUG: Input details are, ${p1} : ${p2} : ${p3}"
}
Output:
DEBUG: Input details are, 1234 : a0 : 12
DEBUG: Input details are, 1111 : b0 : 34
The good thing is that this approach prevents IndexOutOfBoundsException
or NullPointerException
. If we change the first line to
def inputDetails = "1234-a0-12;1111-b0"
the result is:
DEBUG: Input details are, 1234 : a0 : 12
DEBUG: Input details are, 1111 : b0 : null
Solution 2
You can split the string into a 2D list by further splitting on '-':
def inputDetails = "1234-a0-12;1111-b0-34"
def elements = inputDetails.split(';').collect{it.split('-')}
elements
is of type List<List<String>>
. When printed, it yields:
[[1234, a0, 12], [1111, b0, 34]]
With this, you can afford more flexibility instead of hard-coding array indexes.
And with "1234-a0-12;1111-b0"
, it's split into [[1234, a0, 12], [1111, b0]]
Yash
Updated on July 30, 2022Comments
-
Yash over 1 year
I want to split an input parameter
inputDetails
to unit level. I'm using tokenize for doing this. Here is my code:Groovy Code:
def inputDetails = "1234-a0-12;1111-b0-34"; def cDesc = inputDetails.tokenize(";"); for (int i=0; i<cDesc.size(); ++i) { def cVer = cDesc.get(i); def cNum = cVer.tokenize("-"); def a = cNum.get(0); def b = cNum.get(1); def c = cNum.get(2); println (" DEBUG : Input details are, ${a} : ${b} : ${c} \n"); }
Output:
DEBUG : Input details are, 1234 : a0 : 12 DEBUG : Input details are, 1111 : b0 : 34
This output is correct and expected. But if I change the first line of Groovy code to following:
def inputDetails = "1234-a0-12;1111-b0";
I get following error message:
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 at java_util_List$get$6.call(Unknown Source) at Script1.run(Script1.groovy:9)
How can I fix it to prevent getting
IndexOutOfBoundsException
while supporting both,1234-a0-12;1111-b0-34
and1234-a0-12;1111-b0
inputs? -
Yash almost 6 yearsHi Ernest, Your suggestion of splitting into a 2D array works but the result is an array form of my input: [[1234, a0, 12], [1111, b0, 34]]. I want to use each of the elements for a different purpose, how do i get 1234, a0, 12.. as seperate elements.
-
ernest_k almost 6 years@Yash It's just a normal list of lists. You can just do a for-each:
elements.each{list -> def a = list[0]; def b = list[1], }...
and you can check the length of the list to know how many elements it contains. -
Yash almost 6 yearsThanks for your help!
-
Yash almost 6 yearsThanks Szymon for making the problem statement more meaningful and the proposed solution.
-
Adam over 5 yearsIt's a missed opportunity that the original authors of groovy didn't decide on
froody
instead