S.Doyle
S.Doyle

Reputation: 213

I am trying to get one value, while using indexing from 3 Arrays?

name[5] = {Peter, James, Roger, Peter, Josę};

subject[5] = {English, Math, English, Science, Math};

grade[5] = {96, 67, 78, 84, 100};

What I am trying to achieve here is to get the Subject that an individual has received their highest mark. Note the duplicate of names in the name Array, this is the same person. What I have attempted to do is use a map in order to achieve the results, however with 3 Arrays it is quite tricky for the level of java that I currently have. I would like to get the name of the student, match it to their grades and pick the Subject which has the highest grade, so basically the return will be one value, per students name. So like this,

English Math English Math

Upvotes: 1

Views: 53

Answers (3)

Sandip Singh
Sandip Singh

Reputation: 85

Java 8 Solution: I would compose an Object and discard the one with the lowest marks. Please find the code snippet below.

public class Main {

public static void main(String[] args) {
    String[] names = {"Peter", "James", "Roger", "Peter", "Jose"};
    String[] subjects = {"English", "Math", "English", "Science", "Math"};
    int[] grades = {96, 67, 78, 84, 100};
    System.out.println(getStudentWithHighScoredSubjects(names, subjects, grades));
}

public static Map<String, String> getStudentWithHighScoredSubjects(String[] names, String[] subjects, int[] grades) {
    return IntStream.range(0, names.length)
            .mapToObj(i -> new StudentHighestGradeSubject(names[i], subjects[i], grades[i]))
            .collect(Collectors.toMap(StudentHighestGradeSubject::getName, Function.identity(), (s1, s2) -> {
                if (s1.getGrade() > s2.getGrade()) {
                    return s1;
                } else {
                    return s2;
                }
            }, LinkedHashMap::new))
            .entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey, e-> e.getValue().getHighestGradeSubject(), (s1, s2) -> s2, LinkedHashMap::new));
}

private static class StudentHighestGradeSubject {
    private String name;
    private String highestGradeSubject;
    private int grade;

    public StudentHighestGradeSubject(String name, String highestGradeSubject, int grade) {
        this.name = name;
        this.highestGradeSubject = highestGradeSubject;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getHighestGradeSubject() {
        return highestGradeSubject;
    }

    public void setHighestGradeSubject(String highestGradeSubject) {
        this.highestGradeSubject = highestGradeSubject;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StudentHighestGradeSubject that = (StudentHighestGradeSubject) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

}

The above gives the following output on execution

{Peter=English, James=Math, Roger=English, Jose=Math}

Upvotes: 0

dave
dave

Reputation: 64657

First I would get a list of indices associated with each name:

HashMap<String, List<Integer>> map = new HashMap<String, List<Integer>>();
int index = 0;
for (String n: name) {
    if (!map.containsKey(n)) {
        map.put(n, new ArrayList<Integer>());
    }
    map.get(n).add(index);
    index++;
}

Then I would iterate over each name:

for (String name : map.keySet()) {

get their indices, and find the index of the max score:

    List<Integer> indices = map.get(name);
    int maxScore = 0, maxIndex = 0;

    for (int index: indices) {
        if (grades[index] > maxScore) {
            maxIndex = index;
        }
    }

And then I would print out the same index from the subjects array:

    System.out.println(name + " did best in " + subject[index]);
}

Upvotes: 1

Tom G
Tom G

Reputation: 3650

I would create a method called getStudentsHighestMark that takes the name and the grade data. The method would iterate over the grades and only consider those grades by the student in question. You need an int to track the highest grade you've seen for that name, and a string for the course that grade corresponds to. After you iterate over the grades simply return the course name for the student's highest mark. Something like this:

public static void main(String[] args) {
    String[] names = {"Peter", "James", "Roger", "Peter", "Jose"};
    String[] subjects = {"English", "Math", "English", "Science", "Math"};
    int[] grades = {96, 67, 78, 84, 100};

    String petersBest = getStudentsHighestMark("Peter", names, subjects, grades);
    System.out.println("Peter's best is: " + petersBest); //Peter's best is: English
    String jamesBest = getStudentsHighestMark("James", names, subjects, grades);
    System.out.println("James's best is: " + jamesBest);  //James's best is: Math
    String rogersBest = getStudentsHighestMark("Roger", names, subjects, grades);
    System.out.println("Roger's best is: " + rogersBest);  //Roger's best is: English
    String josesBest = getStudentsHighestMark("Jose", names, subjects, grades);
    System.out.println("Jose's best is: " + josesBest);  //Jose's best is: Math
}

private static String getStudentsHighestMark(String name, String[] names, String[] subjects, int[] grades) {
    int highestGrade = 0;
    String bestCourse = "";
    for(int i = 0; i < names.length; i++) {
        if(names[i].equals(name) && grades[i] > highestGrade) {
            highestGrade = grades[i];
            bestCourse = subjects[i];
        }
    }
    return bestCourse;
}

Upvotes: 3

Related Questions