UnfreeHeX
UnfreeHeX

Reputation: 83

Still get repeated strings when using 'Distinct()'

Um I am working on a school project. I know its not professional to ask for homework questions, but I am really unsure about this part (was not gone through in class). So I came to my last resort of asking here. So situation is a comparison between two list has to be made, and then print out similar elements.

Current code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LessonXEx4
{
    class Student
    {
        public string strName;
        public float fltGPA;
        public Student(string x, float y)
        {
            strName = x;
            fltGPA = y;
        }
    }

    class Program
    {
        static void DisplayStudents(List<Student> Studentx)
        {
            foreach(Student C in Studentx)
            {
                Console.WriteLine("Student name: " + C.strName + "\nGPA: " + C.fltGPA);
            }
        }
        static List<Student> AddStudentInfo()
        {
            List<Student> Studlist = new List<Student>();
            Student ObjStd;
            string Per = "Y";   
            while (Per == "Y")
            {
                Console.WriteLine("Enter student Name:");
                string N = Console.ReadLine();

                Console.WriteLine("Enter you GPA: ");
                float G = float.Parse(Console.ReadLine());

                ObjStd = new Student(N, G);
                Studlist.Add(ObjStd);

                Console.WriteLine("Do you want to continue: ");
                string Perx = Console.ReadLine();
                Per = Perx;
            }
            return Studlist;
        }
        static void Main(string[] args)
        {
            List<Student> studentlist1 = new List<Student>();
            List<Student> studentlist2 = new List<Student>();
            Console.WriteLine("Group 1:\n");
            studentlist1 = AddStudentInfo();
            Console.WriteLine("\n\nGroup 2:\n");
            studentlist2 = AddStudentInfo();
            Console.WriteLine("\n\nGroup 1:\n");
            DisplayStudents(studentlist1);
            Console.WriteLine("\n\nGroup 2:\n");
            DisplayStudents(studentlist2);
            foreach (Student Fx in studentlist1)
            {
                foreach (Student fX in studentlist2) 
                {
                    if (Fx.fltGPA == fX.fltGPA)
                    {
                        List<String> Nam = new List<string>();
                        Nam.Add(fX.strName);
                        Nam.Add(Fx.strName);
                        Nam.Distinct().ToArray();
                        Console.WriteLine("\n" + fX.fltGPA);
                        Nam.ForEach(item => Console.WriteLine(item));
                    }
                }
            }
                        Console.ReadLine();
        }
    }
}

Current output:

Group 1:

Enter student Name:
qw
Enter you GPA:
12
Do you want to continue:
Y
Enter student Name:
we
Enter you GPA:
12
Do you want to continue:
Y
Enter student Name:
er
Enter you GPA:
12
Do you want to continue:
N


Group 2:

Enter student Name:
as
Enter you GPA:
12
Do you want to continue:
Y
Enter student Name:
sd
Enter you GPA:
12
Do you want to continue:
Y
Enter student Name:
df
Enter you GPA:
12
Do you want to continue:
n


Group 1:

Student name: qw
GPA: 12
Student name: we
GPA: 12
Student name: er
GPA: 12


Group 2:

Student name: as
GPA: 12
Student name: sd
GPA: 12
Student name: df
GPA: 12

12
as
qw

12
sd
qw

12
df
qw

12
as
we

12
sd
we

12
df
we

12
as
er

12
sd
er

12
df
er

Though I tried .Distinct() in the Nam list, Its still repeating the names. I don't want it to repeat them. What I expected is:

12
qw
we
er
as
sd
df

or even better:

Student(s) with GPA of 12 are: qw, we, er, as, sd, df

Something like that. Any help will be really appreciated.

Upvotes: 1

Views: 106

Answers (2)

Caius Jard
Caius Jard

Reputation: 74605

Though I tried .Distinct() in the Nam list, Its still repeating the names. I don't want it to repeat them.

But, you have a loop inside a loop, so the inner loop will be repeated as many times as there are items in the outer loop

If you want to merge studentlist1 and studentlist2 you can just add them all to a new list

var allStudents = new List<Student>();

allStudents.AddRange(studentList1);
allStudents.AddRange(studentList2);

Student(s) with GPA of 12 are: qw, we, er, as, sd, df

This looks like you want to group students by GPA. You probably havent been taught LINQ in depth yet (though I see you're using some linq methods) but Dictionary may have been covered

Dictionary provides a way to map a key to a value. The key (one of) will be GPA. Because there will be many values with the same key, we will use a list to hold the values.

var d = new Dictionary<float, List<Student>>();

foreach(var s in allStudents){
  //ensure the dictionary knows of this gpa value
  if(!d.ContainsKey(s.fltGpa))
    d[s.fltGpa] = new List<Student>();

  //add the student to the list of students mapped to this GPA
  d[s.fltGpa].Add(s);
}

Now you have a dictionary that has lists per different gpa. If you had 2 students with a gpa of 4 and 1 student with a gpa of 5 your Dictionary would be like:

d[4] -> { Student, Student }
d[5] -> { Student }

The dictionary is effectively a list of KeyValuePair<float, List<Student>> ie a list of lists - something you can use two loops on:

foreach(var kvp in d) // for every keyvaluepair
{
  Console.WriteLine("Students with a GPA of " + kvp.Key); //Key is a float of the gpa

  foreach(var s in kvp.Value) //value is a List<Student>
    Console.Write(s.strName + " ");
}
  

Once you understand this it puts you in good stead to understanding grouping in linq. A group operation produces a result where it's like a bunch of lists and every list has a Key property that is what all the elements in the list were grouped on

var groups = allStudents.GroupBy(st = st.fltGpa);

This is somewhat similar to the loop that prepares the dictionary. groups is like an array of lists (I'm calling them something different do I can refer to them more easily), every item in the inner list is a student,and the inner list has a Key that is the gpa of every student in the inner list. In the outer array there is one list per different gpa, this means for four students, three that have gpa 4 and one that has gpa 5, would become an array of size two (two different gpa values), the first element in the array is a list of length 3 and Key of 4 (three students have a gpa of 4). The second element in the array is a list of length 1 and Key of 5 (one student has a gpa of 5)

These things aren't actually arrays and lists but ultimately they look like a dictionary we saw before - in essence a way of collecting together all the students that have the same gpa into one list, and having a list per different gpa

Upvotes: 2

mdisibio
mdisibio

Reputation: 3520

Thank you for stating it's a homework problem. You are almost there. Where you write:

Nam.Distinct().ToArray();
Nam.ForEach(item => Console.WriteLine(item));

is where you have a slight problem. Distinct() does not alter your list. It gives you a result with the distinct values, while leaving the original list intact. You would need to save that result and print those values rather than the original list:

var distinctNames = Nam.Distinct().ToList();
distinctNames.ForEach(item => Console.WriteLine(item));

Upvotes: 2

Related Questions