Home > Software design >  How to turn a String into a nested Array
How to turn a String into a nested Array

Time:11-23

I get a String of the format <num-num-num><num-num-num><num-num-num>. I want to turn this into a nested Array of Ints with each Array being the content between the <>.

This is what I got so far:

String parameter = args[1];
// split the string into an array of strings at >

String[] splitString = parameter.split(">");
int[][] square = new int[splitString.length][splitString.length];

// remove <, > and - characters and push the numbers into the square

for (int i = 0; i < splitString.length; i  ) {
    splitString[i] = splitString[i].replaceAll("[<>-]", "");

    for (int j = 0; j < splitString.length; j  ) {
        square[i][j] = Integer.parseInt(splitString[i].substring(j, j   1));
    }
}

I don't feel like this is very clean, but it works. Does anyone have an idea on how to improve readability?

CodePudding user response:

I assume "<num-num-num><num-num-num><num-num-num>" would define a 3x3 grid so I would use the following approach:

  • split the string into a string per row so we get "num-num-num". That means:
    • remove the leading and trailing angular brackets
    • split at "><" and remove it
  • split each row at "-" to get the individual numbers
  • parse the numbers and assign them to the grid

Some code example:

String input = "<11-12-13><21-22-23><31-32-33>";
 
//remove leading < and trailing > then split at ><   
String[] inputRows = input.substring(1,input.length()-1).split("><");
    
int[][] grid = new int[inputRows.length][];
    
for( int r = 0; r < inputRows.length; r  ) {
    //split the row at -
    String[] cells = inputRows[r].split("-");
        
    //convert the array of strings to an array of int by parsing each cell
    grid[r] = Arrays.stream(cells).mapToInt(Integer::parseInt).toArray();
}

CodePudding user response:

Here's how it can be done using Java 9 Matcher.results().

First, let's define a pattern that captures a group of digits interlaid with dashes -:

public static final Pattern ANGLE_BRACKETS = Pattern.compile("<([\\d-]*)>");

Using this pattern, we can create a matcher, and with Matcher.results() generate a stream of MatchResults, which is an object representing the captured sequence of characters.

We can obtain the matching substring using MatchResult.group() (1 should be passed as an argument, since we need a substring without brackets).

To split each group, we can use either Pattern.splitAsStream() or Arrays.split(). In this case, the latter is preferred because splitting a string on dashes "-" can be done without compiling a regular expression and utilizing regex engine. Pattern.splitAsStream() might be more beneficial when array is large (splitAsStream() generates a stream directly from the regex engine with need to allocate an intermediate array), or we need to split a string using a regex, and not a regular string like "-".

String parameter = "<1-2-3><4-5-6><7-8-9>";
    
int[][] matrix = ANGLE_BRACKETS1.matcher(parameter).results()
    .map(matchResult -> matchResult.group(1))
    .map(str -> Arrays.stream(str.split("-")).mapToInt(Integer::parseInt).toArray())
    .toArray(int[][]::new);
    
System.out.println(Arrays.deepToString(matrix));

Output:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  • Related