Extracting the last action of last employee

115 views Asked by At
        5023971 s   2016-05-22 21:34:48     
        5023971 s   2016-05-22 21:35:57     
        5023971 s   2016-05-22 21:36:35     
        5023971 s   2016-05-22 21:37:42     
        5023971 s   2016-05-22 21:39:41 3   sple
        5296256 d   2016-03-04 08:05:12     
        5296256 d   2016-03-04 08:05:13     
        5296256 d   2016-03-04 08:05:14 4   sup
        5324887 d   2016-05-06 10:22:22     
        5324887 d   2016-05-06 10:22:30 2   sup
        79159   r l 2016-03-13 16:33:59 1   roy
        1318887 g a 2016-03-15 11:59:09 2   gg
        1318887 g a 2016-03-21 13:26:13 1   gglrt
        4821757 y a 2016-05-24 19:46:39 8   hnd

Consider we have a list of employees that contains the employee id, name, time, a random number and an action performed by the employee. the name is either one or two tokens but the actions are always with one token. What we are interested to do is to extract the last action that an employee performs with his/her name.(for example: s and sam, d and sup etc.) The code below does the job but it extracts the first action of each distinct employee. How to modify it to meet the requirement?

 static StringTokenizer a;
 public static boolean isInteger(String s) {
try { 
    Integer.parseInt(s); 
} catch(NumberFormatException | NullPointerException e) { 
    return false; 
}
    return true;
 }

 static boolean first=true;

    public static void main(String[] args) {


    BufferedReader br=new BufferedReader(file);

    String line;
    String name="";
    String tempaction="";
    String action="";

    while((line=br.readLine())!=null){

                  int  nameLenght=0;
                  String tempName="";
                  String temp2;
                  String temp3;
                    a=new StringTokenizer(line);

                  if(first){
                    while(a.hasMoreTokens()){
                        temp2=a.nextToken();
                        temp3=temp2.charAt(0)+"";
                        if((temp2).startsWith("2016") ) break;
                        if(!isInteger(temp3)){
                            nameLenght++;
                            tempName=tempName+" "+temp2;

                        }


                    }
                       if(nameLenght<3 && !name.equals(tempName)){

                            name=tempName;
                           System.out.println(name);
                          first=false;
                       }
                  }

                   action="";
                    if(!first){
                      while(a.hasMoreTokens() ){

                        temp2=a.nextToken();
                        temp3=temp2.charAt(0)+"";
                        if((temp2).startsWith("2016") ) break;
                        if(!isInteger(temp3)){
                            action=action+" "+temp2;

                        }                       

                    }

                      if(!tempAction.equals(action)){
                           tempAction=action; 
                           System.out.println(action);
                           first=true;
                          }

                      first=true;
                    }
                    }
    }
1

There are 1 answers

7
Patrick Parker On

Here is one way of getting the last action for each employee (using Java 8 Streams and Regular Expression matching)

private static final Pattern LINE_REGEX = Pattern.compile(
        "^\\s*" // space before user id
        + "[0-9]+" // user id
        + "\\s+" // space after user id
        + "(.*?[^\\s])" // user name (group 1)
        + "\\s+" // space after user name
        + "([0-9]+-.{14})" // timestamp (group 2)
        + "\\s+" //space after timestamp
        + "[0-9]*" // random int
        + "\\s+" //space after random int
        + "(.*[^\\s])" // user action (group 3)
        + "\\s*$" // space after user action
);
public static void main(String[] args) throws IOException {
    try(Stream<String> stream = Files.lines(Paths.get("emplog.txt"))) {
        Map<String,String> result = stream.map(LINE_REGEX::matcher)
            // filter out any lines without an Action
            .filter(Matcher::matches)
            // group by User
            .collect(Collectors.groupingBy((Matcher m) -> m.group(1),
                Collectors.collectingAndThen(
                    // compare Timestamp (min for earliest, max for latest)
                    Collectors.maxBy(Comparator.comparing((Matcher m) -> m.group(2))),
                    // extract Action
                    (Optional<Matcher> m) -> m.get().group(3))));
        System.out.println(result);
    }
}

Output:

{s=sple, d=sup, g a=gglrt, y a=hnd, r l=roy}

(If any users have no actions, they will not be listed.)