Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java:how to group similar strings (items) to respective array (group)?

Tags:

java

I have the following string "0#Aitem, 0#Aitem2, 0#Aitem3, 1#Bitem, 1#Bitem2, 2#Citem, Nitem, Nitem2".

the 0# shows group number. so Aitem, Aitem2, Aitem3 will belong to group 0. Bitem, Bitem2 in group 1. Citem in group 2. If there is no group number, they will all be place in separate group. So Nitem, Nitem2 will be placed in group 3.

I would like to create an array for each group, and place the "items" in respective group(array). So I would end up with something like

[array("Aitem,Aitem2,Aitem3"), array("Bitem, Bitem2"), array("Citem"), array("Nitem, Nitem2")]

I am guessing I need an arrayList to hold all the groups (arrays) which respectively has appropriate elements (items).

This is what I started with but I don't know if this is the best approach. The string is dynamic, so there can be any number of groups and has to follow the criteria above.

String[] x = Pattern.compile(",").split("0#item, 0#item2, 0#item3, 1#item, 1#item2, 2#item, item");
   for (int ii=0; ii<x.length; ii++) {
       System.out.println(i + " \"" + x[ii] + "\"");
   }
like image 681
KJW Avatar asked Dec 09 '22 12:12

KJW


2 Answers

My answer shows how you can use a single regex to extract both the group and the item. You can then store these in a map.

    String s =  "0#Aitem, 0#Aitem2, 0#Aitem3, 1#Bitem, 1#Bitem2, 2#Citem, Nitem, Nitem2";
    Pattern p = Pattern.compile("(\\d*)[#]{0,1}(\\w+?)(,|$)");        
    Matcher m = p.matcher(s);
    Map<String, List<String>> map = new TreeMap<String, List<String>>();
    while(m.find()){
        String group = m.group(1);
        String item = m.group(2);
        List<String> items = map.get(group);
        if(items == null){
            items = new ArrayList<String>();
            map.put(group, items);
        }
        items.add(item);
    }
    //let's print it out
    for(String key : map.keySet()){
        System.out.println(key + " : " + map.get(key));
    }

prints:

 : [Nitem, Nitem2]
0 : [Aitem, Aitem2, Aitem3]
1 : [Bitem, Bitem2]
2 : [Citem]

At the moment, items with no group are keyed against an empty string. I'll leave it at as an exercise for you to handle this scenario. It should simply be a case of finding the max key and incrementing it.

I'm sure the regex can be improved too as it was written in haste.

like image 121
dogbane Avatar answered Apr 28 '23 07:04

dogbane


//Create a map for storing groups
Map<String, Collection<String>> groupMap = new HashMap<String, Collection<String>>();

String[] parts = yourString.split("[, ]+"); //Split by each word
for (String part : parts) {   //Go over all words
    String[] subparts = part.split("#"); //Split to index and value

    String groupKey;
    String value;
    if (subparts.length == 1) { //There is no '#' sign
        groupKey = null;
        value = subparts[0];
    } else if (subparts.length == 2) { //There is one '#'sign
        groupKey = subparts[0];
        value = subparts[1];
    } else {
        throw new IllegalArgumentException("Can not parse string");
    }

    Collection<String> groupContents = groupMap.get(groupKey); //Extract list of items in this group
    if (groupContents == null) { //If there was no such group yet - create one
        groupMap.put(groupKey, groupContents = new ArrayList<String>());
    }
    groupContents.add(value); //Add item to group
}
like image 25
bezmax Avatar answered Apr 28 '23 05:04

bezmax