user1151923
user1151923

Reputation: 1872

how to check if property value of each list member is same

So say I have a class Student with one property, int Age. Now if I have List<Student> students, how do I check if the age of all students in the list is equal?

Upvotes: 15

Views: 14338

Answers (6)

black.rook
black.rook

Reputation: 41

If you just have to check this once, the marked answere is best solution. To use it multiple times in your code just write a static extension to check equality of property:

public static bool GetIdenticProperty<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> predicate)
{
    IEnumerable<TSource> enumerable = source as IList<TSource> ?? source.ToList();
    if ((!enumerable.Any()) || (enumerable.Count() == 1))
        return true; // or false if you prefere
    var firstItem = enumerable.First();
    bool allSame = enumerable.All(i => Equals(predicate(i), predicate(firstItem)));
    return allSame;
}

If you want to use the value of the property later on lets return that value:

public static TKey GetIdenticProperty<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> predicate)
{
    IEnumerable<TSource> enumerable = source as IList<TSource> ?? source.ToList();
    if (!enumerable.Any())
        return default(TKey);
    var firstItem = enumerable.First();
    bool allSame = enumerable.All(i => Equals(predicate(i), predicate(firstItem)));
    return allSame ? predicate(firstItem) : default(TKey);
}

But using this code you have to check weather the returnd value is null or default(TKey) relating to the type of property.

Upvotes: 0

Alex Siepman
Alex Siepman

Reputation: 2598

If students can have 0 elements you can do this:

var firstStudent = students.FirstOrDefault();
var areSame =students.All(s => s.Age == firstStudent.Age);

Upvotes: 3

SysDragon
SysDragon

Reputation: 9888

If you can't use linq, you can always loop all the students:

private bool sameAge (List<Student> students)
{
    int auxAge = students.Count > 0? students[0].Age : 0;

    foreach (Student stu in students)
    {
        if (stu.Age != auxAge) 
            return false;
    }
    return true;
}

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062492

Just a random answer - not sure I'd do it this way in reality, but this will be brutally efficient:

  • will use typed iterators if duck-typing is available (unlike LINQ which won't) - and note that List<T> does offer duck-typed iterators
  • no double-iterations
  • no failures etc for empty sequences
  • no delegates, capture-contexts, etc
  • etc

Code:

using(var iter = students.GetEnumerator()) // a List<T>.Enumerator struct
{
    if(!iter.MoveNext()) return true; // or false, as you define for "empty"

    int age = iter.Current.Age;
    while(iter.MoveNext())
        if(iter.Current.Age != age)
            return false;
    return true;
}

Upvotes: 4

Rawling
Rawling

Reputation: 50104

If you want to do this in one query, not two (which is generally bad practice),

bool allAgesAreTheSame = (students.Select(s => s.Age).Distinct().Count() < 2);

will do it for you.

This will also return true in the trivial case where you have no students at all, rather than throw an exception. (You could do == 1 rather than < 2 to return false in the trivial case instead.)

Upvotes: 11

cuongle
cuongle

Reputation: 75296

You can check by using All method, presumably your list have students:

var firstStudent = students.First();
students.All(s => s.Age == firstStudent.Age);

Upvotes: 32

Related Questions