Search code examples
javacsvbufferedreader

How to count the number of name occurence and assign point to it?


I have csv file. Structure is like this

First  Second  Third
Alex   Peter   Max
Peter  Alex    John
Steven James   John
Steven James   John
Max    John    Steven

I want to read all lines and assign point according to places, e.g. Alex will got 3 points for every mentioning in First place, 2 points in Second and 1 point in Third. So final output should show all names with assigned points. It should be like this

Steven - 7 points (3 + 3 + 1)
Alex - 5 points (3 + 2)
Peter - 5 points (3 + 2)
Max - 4 points (3 + 1)
James - 4 points (2 + 2)
John - 4 points (2 + 2)

Below is my code

public class Main {

    private final static String FILE_PATH = "Table.csv";
    private final static String FIRST_PLACE = "First";
    private final static String SECOND_PLACE = "Second";
    private final static String THIRD_PLACE = "Third";

    public static void main(String[] args) {

        try {
            BufferedReader br = new BufferedReader(new FileReader(FILE_PATH));
            String s;
            List<String> firstName = new ArrayList<>();
            while ((s = br.readLine()) != null){
                firstName.add(s);
            }
            Map<String, Long> sortedName = firstName.stream()
                    .collect(groupingBy(chr -> chr, counting()))
                    .entrySet().stream()
                    .sorted(Map.Entry.comparingByValue(Collections.reverseOrder()))
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue,
                            (e1, e2) -> e1,
                            LinkedHashMap::new
                    ));
            sortedName.forEach((k, v) -> System.out.println("Name: " + k + " || " + "Count: " + v));
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }
}

But it counts line by line and count column name also and gives this output

Name First  Second  Third || Count 1
Name Alex   Peter   Max || Count 1
Name Peter  Alex    John || Count 1
Name Steven James   John || Count 2
Name Max    John    Steven || Count 1

Solution

  • The pseudo-code you need is:

    for each in line (except first) in from file
        read line
        tokenize line to string array of size 3
        for each token
            if name is present in map
                map.put(name, map.get(name)+(3-i)) //i is index of token travesal loop
            else
                map.put(name, (3 - i))
    
    map.entrySet().stream()
                    .sorted((k1, k2) -> -k1.getValue().compareTo(k2.getValue()))
                    .forEach(k -> System.out.println(k.getKey() + ": " + k.getValue())); // Print while ordering the map by values