0

I need a function to change a String like this:

Red, Green, Blue, Orange, Pink, Gray, Purple

Into a String[] like this:

Red, Green,
Blue, Orange,
Pink, Gray,
Purple

In this example the character is , and splitting it every 2nd. There are many similar functions online to this one, but they all remove the character.

likse
  • 9
  • 2
  • 2
    You can use String's [`indexOf(int ch, int fromIndex)`](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int,%20int)) repeatedly to find the index of the n-th delimeter. – f1sh Jul 27 '20 at 23:23
  • And how exactly could that be done? I can't wrap my head around it. – likse Jul 27 '20 at 23:54
  • Walking through the input string from left to right using an integer to keep track of your current position. Use the indexOf function to advance to the next comma character. Then every other comma add a newline. There's a special case when you reach the end of the input string and there's an odd number of words. – user3112728 Jul 28 '20 at 02:24

4 Answers4

1

this should work fine.

    String sample = "Red, Green, Blue, Orange, Pink, Gray, Purple";
    ArrayList<String> output = new ArrayList<>();

    Pattern firstPattern = Pattern.compile("[a-zA-Z-\\s]*,[a-zA-Z-\\s]*,|[a-zA-Z-\\s]*,[a-zA-Z-\\s]*");
    Matcher firstMatcher = firstPattern.matcher(sample);
    Pattern secondPattern = Pattern.compile("[a-zA-Z-\\s]*$");
    Matcher secondMatcher = secondPattern.matcher(sample);

    while (firstMatcher.find()) {
        output.add(firstMatcher.group());
    }
    if ((output.size() * 2) < sample.split(",").length)
        if (secondMatcher.find())
            output.add(secondMatcher.group(0));

output:

Red, Green,
 Blue, Orange,
 Pink, Gray,
 Purple
Omar Elashry
  • 29
  • 1
  • 5
1

here is a simple solution that works in linear time O(n)

enter image description here

where groupSize = 2

    public static ArrayList<String> splitPairs(String input, int groupSize) {
    String[] inputArray = input.split(",");
    ArrayList<String> result = new ArrayList<>();
    int index = 0;

    while (index < inputArray.length) {
        StringBuilder newItem = new StringBuilder();

        for (int i = 0; i < groupSize && index < inputArray.length; i++, index++) {
            if (i != 0)
                newItem.append(", ");

            newItem.append(inputArray[index].trim());

            if (i == groupSize - 1) {
                newItem.append(",");
            }
        }

        if (newItem.length() > 0) {
            result.add(newItem.toString());
        }
    }

    return result;
}
Ahmed Ali
  • 785
  • 1
  • 8
  • 15
  • If you have an even number the last one (for example if we remove purple) will keep the comma. – likse Jul 28 '20 at 19:09
0

A not very good solution may help you.

First:split the string by ',' into String[]

Second:split String array into array of string array and every small array have 0,1 or 2 elements

Third:join the small string array.

A solution use google guava:

String input = "Red, Green, Blue, Orange, Pink, Gray, Purple";
List<List<String>> lists = Lists.partition(Arrays.asList(input.split(",")),2);
String[] outputs = new String[lists.size()];
lists.stream().map(strings -> String.join(", ", strings)).map(String::trim)
    .collect(Collectors.toList()).toArray(outputs);
for (String output: outputs) {
    System.out.println(output);
}
TongChen
  • 1,414
  • 1
  • 11
  • 21
0

Here is an approach withouth regex, using the indexOf method that i mentioned in the comment. It's a little oldschool and does all the things manually, essentially just using indexOf and substring, which makes it fulfill your "keeping the character" requirement.

public static void main(String[] args) {
  String input = "Red, Green, Blue, Orange, Pink, Gray, Purple";
  final int n = 2;
  final char delim = ',';
  nthSep(input, n, delim).stream().forEach(System.out::println);
}

private static LinkedList<String> nthSep(String input, int n, char delim) {
  LinkedList<String> res = new LinkedList<>();
  int startsplit = 0;
  int delimcount = 0;
  int curInd = 0;
  //repeat until no separator is found
  while (true) {
    //remember the index of the current split part
    startsplit = curInd;
    delimcount = 0;
    //find the separator n times
    while (delimcount < n) {
      curInd = input.indexOf(delim, curInd+1);
      if (curInd == -1) {
        break;
      }
      delimcount++;
    }

    if(curInd != -1){
      //add a result to the list, then move on with the next split part
      res.add(input.substring(startsplit, curInd+1));
      curInd++;
    } else {
      //so further separator is found, add the whole remaining input
      res.add(input.substring(startsplit));
      break;
    }
  }
  return res;
}
f1sh
  • 11,489
  • 3
  • 25
  • 51