Question

In the below case, I want to get a count of how many times the employee is repeating. For example, if the list has EmpA 25 times, I would like to get it. I am trying with GroupBy but not getting results. I can do record skip and find the count but there are lot of records.

So in below example, lineEmpNrs is the list and I want to have grouping results by employee ID.

Please suggest.

public static string ReadLines(StreamReader input)
{
string line;
while ( (line = input.ReadLine()) != null)
   yield return line;

}

private taMibMsftEmpDetails BuildLine(string EmpId, string EmpName, String ExpnsDate)
{
taMibMsftEmpDetails empSlNr = new taMibMsftEmpDetails();
empSlNr.EmployeeId  = EmpId;
empSlNr.EmployeeName   = EmpName;
empSlNr.ExpenseDate = ExpnsDate;
return empSlNr;

}

List<taMibMsftEmpDetails> lineEmpNrs = new List<taMibMsftEmpDetails>();
foreach (string line in ReadLines(HeaderFile))
{ 
headerFields = line.Split(',');
lineEmpNrs.Add(BuildLine(headerFields[1],headerFields[2],headerFields[3]));
}
Was it helpful?

Solution

You can define following delegate, which you will use to select grouping key from list elements. It matches any method which accepts one argument and returns some value (key value):

public delegate TResult Func<T, TResult>(T arg);

And following generic method, which will convert any list to dictionary of grouped items

public static Dictionary<TKey, List<T>> ToDictionary<T, TKey>(
    List<T> source, Func<T, TKey> keySelector)
{
    Dictionary<TKey, List<T>> result = new Dictionary<TKey, List<T>>();

    foreach (T item in source)
    {
        TKey key = keySelector(item);
        if (!result.ContainsKey(key))
            result[key] = new List<T>();
        result[key].Add(item);
    }

    return result;
}

Now you will be able to group any list into dictionary by any property of list items:

List<taMibMsftEmpDetails> lineEmpNrs = new List<taMibMsftEmpDetails>();
// we are grouping by EmployeeId here
Func<taMibMsftEmpDetails, int> keySelector = 
    delegate(taMibMsftEmpDetails emp) { return emp.EmployeeId; };

Dictionary<int, List<taMibMsftEmpDetails>> groupedEmployees = 
    ToDictionary(lineEmpNrs, keySelector);

OTHER TIPS

GroupBy should work if you use it like this:

var foo = lineEmpNrs.GroupBy(e => e.Id);

And if you'd want to get an enumerable with all the employees of the specified ID:

var list = lineEmpNrs.Where(e => e.Id == 1); // Or whatever employee ID you want to match

Combining the two should get you the results you're after.

If you wanted to see how many records there were with each employee, you can use GroupBy as:

foreach (var g in lineEmpNrs.GroupBy(e => e.Id))
{
  Console.WriteLine("{0} records with Id '{1}'", g.Count(), g.Key);
}

To simply find out how many records there are for a specified Id, however, it may be simpler to use Where instead:

Console.WriteLine("{0} records with Id '{1}'", lineEmpNrs.Where(e => e.Id == id).Count(), id);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top