Home > Software engineering >  Given string filter a part of it based on a pattern then add to array-list
Given string filter a part of it based on a pattern then add to array-list

Time:05-21

Given a string with repeating pattern here:

 String s = NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500
  • Essentially I want way where when NameJJ and firstname are beside each other like at top it stores value beside them which is arraylist1 = [120,200].

  • Essentially I want way where all field with NameBB and secondname are beside each other to store the value beside them which is arraylist2 = [100,300].

  • Essentially I want way where all field with NameJJ and thirdname are beside each other to store the value beside them which is arraylist3 = [150,500].

I was trying to do this to say if string contains NameJJ and contains firstname should filter out value beside it but I'm confused on how I would do that, this is the code :

if (s.contains(NameJJ) && s.contains(firstname))
   Pattern reg = Pattern.compile(",");
ArrayList<String> SANR = reg.splitAsStream(s)    
        .filter(role -> role.contains(""))
        .map(String::trim)
        .collect(Collectors.toCollection(ArrayList::new));

CodePudding user response:

Your String s holds the complete data so if (s.contains(NameJJ) && s.contains(firstname)) will always be true. You have to split the blocks first, then look at the values.

Your data block contains 3 data each so that's the number you have to divide by in loop condition and multiply with in array access

String s = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";
String[] split = s.split(",");
List<Integer> first = new ArrayList<>();
List<Integer> second = new ArrayList<>();
List<Integer> third = new ArrayList<>();
for (int i = 0; i < split.length / 3; i  ) {
    // first data block is Name..
    // second block is firstname/secondname/thirdname
    // third block hold the number you want
    if (split[3 * i].trim().equals("NameJJ") && split[3 * i   1].trim().equals("ABC/firstname")) {
        first.add(Integer.parseInt(split[3 * i   2].trim()));
    } else if (split[3 * i].trim().equals("NameBB") && split[3 * i   1].trim().equals("ABC/secondname")) {
        second.add(Integer.parseInt(split[3 * i   2].trim()));
    } else if (split[3 * i].trim().equals("NameCC") && split[3 * i   1].trim().equals("ABC/thirdname")) {
        third.add(Integer.parseInt(split[3 * i   2].trim()));
    }
}
System.out.println(first);
System.out.println(second);
System.out.println(third);

Output is

[120, 200]
[100, 300]
[150, 500]

CodePudding user response:

As I've answered in a previous question of yours, whenever you're having a certain pattern repeating itself, you should use a regex to extract the sub-bits of your pattern.

Streams are not designed to keep track of a "first" or "last" element. They're mainly stateless operations, with a few exceptions for distinct, sorted and similar. Stateless operations start their execution even before the previous one has finished its computation. This is why they have no recollection of a first or last result and also why we cannot use them for this kind of tasks.

What you could do is to employ 3 regex to match your pattern for nameJJ, nameBB and nameCC, and use capturing groups to identity and extract every desired sub-bit.

The following 3 regex can be used to match your patterns:

(\w )JJ,(\w )\/(\w ),(\d )
(\w )BB,(\w )\/(\w ),(\d )
(\w )CC,(\w )\/(\w ),(\d )

Here is a snippet of the code implementation:

public class Main {
    public static void main(String[] args) {
        String s = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";

        List<Integer> listNameJJ = getList("(\\w )JJ,(\\w )\\/(\\w ),(\\d )", s);
        List<Integer> listNameBB = getList("(\\w )BB,(\\w )\\/(\\w ),(\\d )", s);
        List<Integer> listNameCC = getList("(\\w )CC,(\\w )\\/(\\w ),(\\d )", s);

        System.out.println(listNameJJ);
        System.out.println(listNameBB);
        System.out.println(listNameCC);
    }

    public static List<Integer> getList(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        List<Integer> list = new ArrayList<>();

        while (matcher.find()) {
            list.add(Integer.valueOf(matcher.group(4)));
        }

        return list;
    }
}

Here is also a link to test the code above:

https://ideone.com/TES5UY

CodePudding user response:

Here is another example,

    public class Application {

    public static void main(String[] args) throws NumberFormatException {

        String st1 = "NameJJ,ABC/firstname,120, NameBB,ABC/secondname,100,NameCC,ABC/thirdname,150,NameJJ,ABC/firstname,200,NameBB,ABC/secondname,300,NameCC,ABC/thirdname,500";
        String st2 = "NameKK,ZXY/kname,510, NameQQ,HLM/kname,210, NameKK,ZXY/kname,210,";

        // Test 1
        System.out.println(getValues("NameJJ", "firstname", st1));
        // Test 2
        System.out.println(getValues("NameKK", "kname", st2));
    }

    static List<Integer> getValues(String str1, String str2, String inputString) {

        Pattern p = Pattern.compile("-?\\d (,\\d )*?\\.?\\d ?");
        List<String> value = new ArrayList<String>();
        Matcher m = p.matcher(inputString);
        while (m.find()) {
            value.add(m.group());
        }

        List<String> key = List.of(inputString.split("\\d "));
        List<Integer> result = new ArrayList<Integer>();

        for (int i = 0; i < value.size(); i  ) {
            if (key.get(i).trim().contains(str1) && key.get(i).trim().contains(str2)) {
                result.add(Integer.parseInt(value.get(i).trim()));
            }

        }
        return result;
    }
}

Console O/P:

 [120, 200]
 [510, 210]
  • Related