Yash
Yash

Reputation: 3114

Splitting a string using a delimiter in Groovy and avoiding IndexOutOfBoundsException

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 and 1234-a0-12;1111-b0 inputs?

Upvotes: 2

Views: 20215

Answers (2)

Szymon Stepniak
Szymon Stepniak

Reputation: 42184

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

Upvotes: 4

ernest_k
ernest_k

Reputation: 45309

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]]

Upvotes: 2

Related Questions