Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count and distinct count in one LINQ expression

Tags:

c#

.net

linq

c#-4.0

Is there anyway to combine the 2 linq expressions into one? I.e. so one LINQ expression will return both the DistCount and the NormCount into the 2 separate int variables.

DistCount = (from string row in myList[i]
                where row.Length > 0
                select row).Distinct().Count();

NormCount = (from string row in myList[i]
                where row.Length > 0
                select row).Count();
like image 557
toop Avatar asked Feb 22 '23 10:02

toop


2 Answers

do a group by row. You'll then have the distinct count (# of groups) and the total (sum of Counts)

var q = (from string row in myList[i]
    where row.Length > 0
    group row by row into rowCount
    select new {rowCount.Key, rowCount.Count})

int distinct = q.Count();
int total = q.Sum(r=>r.Count);
like image 83
D Stanley Avatar answered Mar 08 '23 06:03

D Stanley


To answer your question. There's no built-in linq expression for that.

Side note. If you really need it you can create one.

public static class Extensions
{
    public static Tuple<int, int> DistinctAndCount<T>(this IEnumerable<T> elements)
    {
        HashSet<T> hashSet = new HashSet<T>();
        int count = 0;
        foreach (var element in elements)
        {
            count++;
            hashSet.Add(element);
        }

        return new Tuple<int, int>(hashSet.Count, count);
    }
}

You can create your named return type instead of Tuple to make the usage easier.

Example usage will look like:

   var distinctAndCount = (from string row in myList[i]
                              where row.Length > 0 
                              select row
                             ).DistinctAndCount();

Or as I personally would prefer to write it:

   var distinctAndCount = myList[i].Where(row => row.Length > 0).DistinctAndCount();
like image 26
Max Galkin Avatar answered Mar 08 '23 07:03

Max Galkin