假设我有一个名为 Student 的类,其中有一个属性 int Age
。现在如果我有一个 List<Student> students
,如何检查列表中所有学生的年龄是否相等?
您可以通过使用All
方法来检查,假设您的列表具有学生:
var firstStudent = students.First();
students.All(s => s.Age == firstStudent.Age);
如果您希望在一次查询中完成此操作,而不是两次(这通常是不良做法),
bool allAgesAreTheSame = (students.Select(s => s.Age).Distinct().Count() < 2);
它也会在你根本没有学生的情况下返回真值,而不是抛出异常。(你可以用 == 1
来代替 < 2
来在这种琐碎的情况下返回假值。)
Distinct()
和Count()
之间添加Take(2)
,这将允许一定程度的短路 - 但是,它会增加额外的迭代器开销 - 因此,这是否是一个好事取决于大量不同年龄是否可能发生。 - Marc GravellCount
而不是只需要 "0、1 或 2
" 感到非常失望,通常我很擅长发现这种问题。 - Rawling仅供参考-实际中不确定是否采用这种方式,但它将非常有效:
List<T>
确实提供鸭子类型的迭代器代码:
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;
}
var firstStudent = students.FirstOrDefault();
var areSame =students.All(s => s.Age == firstStudent.Age);
如果您只需要检查一次,那么标记的答案是最佳解决方案。如果您需要在代码中多次使用它,请编写一个静态扩展来检查属性的相等性:
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;
}
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);
}
但是使用这段代码时,您需要检查返回值是否与属性类型相关的null
或default(TKey)
。
如果您无法使用linq,您始终可以循环遍历所有学生:
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;
}