I would like to get the count a particular property of an object appears in a collection. Here’s the object
public class Candidate {
public string Qualification {get; set;}
public string Name {get; set;}
}
Qualification can be 1 of 5 things, High School, Associates, Bachelors, Masters, and PhD
In this case, I want to see whether the same Qualification occurs more than once in a collection of candidates. Here’s my method so far
public (string, int) GetQualificationCountAsync(List<Candidate> candidates)
{
var roleCount = new Dictionary<string, int>();
foreach (var candidate in candidates)
{
if (roleCount.ContainsKey(candidate.Qualification)) roleCount[candidate.Qualification] += 1;
else roleCount[candidate.Qualification] = 1;
}
var maxCount = roleCount.Values.Max();
if (maxCount <= 1) return (string.Empty, 0);
var key = string.Empty;
foreach (var keyValuePair in roleCount.Where(keyValuePair => EqualityComparer<int>.Default.Equals(keyValuePair.Value, maxCount)))
key = keyValuePair.Key;
return (key, maxCount);
}
Is there a cleaner way of retrieving this information?
>Solution :
You can do it in one line statement like so:
public static List<( String qualification, Int32 count )> GetNondistinctQualifications( IEnumerable<Candidate> candidates )
{
return candidates
.GroupBy( c => c.Qualification )
.Where( grp => grp.Count() >= 2 )
.Select( grp => ( qual: grp.Key, count: grp.Count() ) )
.ToList();
}
If it helps to explain it: if this were SQL, the equivalent would be:
(Remember in SQL, the logical order-of-operations is FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY, which is why COUNT(*) is used twice, despite it being obviously redundant (blame the ISO commitee that designed SQL))
SELECT
c.Qualification,
COUNT(*) AS "Count"
FROM
candidates AS c
GROUP BY
c.Qualification
HAVING
COUNT(*) >= 2