0

I would like to add classStudents to the list _ClassStudents only if classStudents is not yet in the list.

public class ClassStudents{

   public Id {get; set;}
   public Name {get; set;}
   public List<Student> Student {get; set;}

}



public static List<ClassStudents> _ClassStudentsList = new List<ClassStudents>();

  public static void addClassStudents(ClassStudents classStudents)
  {
          //if( classStudents isn't in ClassStudentsList ) <------
           _ClassStudentsList.Add(classStudents);
   }

How can I do this?

Amadeu Antunes
  • 678
  • 1
  • 8
  • 28
  • If `turma` is a type (user class) then follow the convention to use UpperCase (a.k.a. [PascalCase](https://msdn.microsoft.com/en-us/library/x2dbyw72(v=vs.71).aspx)) in order to distinguish it from the variable/field name `turmas`. Also `addTurma` is superfluous to the code and question. – John Alexiou Jul 30 '17 at 14:09
  • what about value, can it be different? – Chirag Rupani Jul 30 '17 at 14:11
  • 1
    'numericUpDown1.Value' can has any number up 0 but it can be repetited in list – Amadeu Antunes Jul 30 '17 at 14:13

3 Answers3

6

You can use the Any extension method:

var text = nameClassStudents.Text;
if(!_ClassStudentsList.Any(t => t.Text == text))
{
    _ClassStudentsList.Add(new ClassStudents(text,(int)numericUpDown1.Value));
}

However, this does not guarantee that names will be unique in the list. If you want it guaranteed, you can simply use a Dictionary<string, int> instead of a List<ClassStudents>.
The Dictionary will not allow duplicate keys.
Of course, here you would also want to check if the key exists before adding a value to the dictionary:

var dict = new Dictionary<string, int>;
...

var text = nameClassStudents.Text;
if(!dict.ContainsKey(text))
(
    dict.Add(text, (int)numericUpDown1.Value);
)
Amadeu Antunes
  • 678
  • 1
  • 8
  • 28
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • This assumes that each `turma` type will always contain two fields, one of which is the key. In the future you are boxing yourself in. – John Alexiou Jul 30 '17 at 14:39
  • Yes, you are correct. That is my assumption. However, it's quite easy to use a `Dictionary` and just use the `turma.Name` as the key. A technique I've used before several times. – Zohar Peled Jul 30 '17 at 14:41
  • 1
    I was some days trying get a solution https://pt.stackoverflow.com/questions/225116/como-verificar-se-um-item-j%C3%A1-foi-introduzido-numa-lista-em-c – Amadeu Antunes Jul 30 '17 at 14:45
  • Right!, i would try to look for the item and if 0 values returned that means the item is not there – Mike Aug 14 '18 at 16:15
  • @ZoharPeled I edited your answer cause had to change the name of my variables and I'm trying to improve my questions to get questions unban – Amadeu Antunes Mar 05 '19 at 12:23
  • @AmadeuAntunes thanks! It would seem weird if the variable names would be different in the answer and in the question. – Zohar Peled Mar 05 '19 at 12:24
3

You can also use a HashSet:

public class ClassStudents {

   public Id {get; set;}
   public Name {get; set;}

   public override bool Equals(object obj) {
            return this.Name.Trim().ToLower().Equals(((ClassStudents)obj).Name.Trim().ToLower());
   }

   public override int GetHashCode() {
       return this.Name.GetHashCode();
   }
}

In your main(), you can declare a HashSet like below:

HashSet <ClassStudents> hash = new HashSet<ClassStudents>();

Now, this will add only unique elements in the set.

Gauravsa
  • 6,330
  • 2
  • 21
  • 30
2

I think the proper way is to tell your program what it means for two Turma types to be equal.

public class ClassStudents
{
    public string Name { get; set; }
    public int Value { get; set; }
    // Override the equality operation to check for text value only
    public override bool Equals(object obj)
    {
        if (obj is ClassStudents other) // use pattern matching
        {
            return Name.Equals(other.Name);
        }
        return false;
    }
}

Now you can use the list method .Contains() for checking if item exists.

{
    List<ClassStudents> classStudents = new List<ClassStudents>();

    public Test()
    {
        // Add three values
        classStudents.Add(new ClassStudents() { Name="ABC", Value=101 });
        classStudents.Add(new ClassStudents() { Name="IJK", Value=111 });
        classStudents.Add(new ClassStudents() { Name="XYZ", Value=101 });

        // Check if exists before adding this value
        ClassStudents x = new ClassStudents() { Name="ABC", Value=121 };
        // `Contains()` calls the `Equals()` method of `classStudents`
        if (!classStudents.Contains(x))
        {
            classStudents.Add(x);
        }
    }

}

This results in the cleanest code because it is obvious what the check if(!classStudents.Contains(x)) does. Also you are leveraging the power of the CLR by adding intelligence to your types. OOP is all about adding methods in your user classes to define actions. In this case, I am definition what equality means for this type and now the CLR can use this information where needed.

Amadeu Antunes
  • 678
  • 1
  • 8
  • 28
John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 3
    While you do make some good points, overriding equals should not be done just for the sake of one test. Equality for this list might not mean equality for other purposes, so I'm not sure that's the correct solution here. Also, using contains is no more readable then using Any. In fact, it's the other way around, since in the Any option you have the comparison condition right in front of you, and you don't need to guess if the equals method was overriden. One more thing, when overriding the equals method you should also override the GetHashCode method. – Zohar Peled Jul 30 '17 at 14:40
  • 1
    the problem with contains is that when you are using classes it will look for the same object and not an object with the same values – Mike Aug 14 '18 at 16:16
  • @Mike - actually no. `Contains()` checks if contents implement `IEquatable` and it uses this instead of a reference equality. I tested the code before I posted. – John Alexiou Aug 14 '18 at 19:48
  • 2
    @ja72 I edited your answer cause had to change the name of my variables and I'm trying to improve my questions to get questions unban – Amadeu Antunes Mar 05 '19 at 12:21