CSharp - Use GroupBy operator with custom Comparer

Introduction

We will implement the IEqualityComparer interface which is defined as follows.

interface IEqualityComparer<T> {
  bool Equals(T x, T y);
  int GetHashCode(T x);
}

This interface requires us to implement two methods, Equals and GetHashCode.

The Equals method is passed two objects of the same type T and returns true if the two objects are considered to be equal or false otherwise.

The GetHashCode method is passed a single object and returns a hash code of type int for that object.

In the following code all Student options records for an Student whose id is less than 100 are grouped with the founders.

Otherwise, they are grouped with the nonfounders.

Demo

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
class Program/*from   w  w w .j a  va  2  s  . com*/
{
    static void Main(string[] args)
    {
        MyFounderNumberComparer comp = new MyFounderNumberComparer();

        StudentOptionEntry[] empOptions = StudentOptionEntry.GetStudentOptionEntries();
        IEnumerable<IGrouping<int, StudentOptionEntry>> opts = empOptions
          .GroupBy(o => o.id, comp);

        //  First enumerate through the sequence of IGroupings.
        foreach (IGrouping<int, StudentOptionEntry> keyGroup in opts)
        {
            Console.WriteLine("Option records for: " + (comp.isFounder(keyGroup.Key) ? "founder" : "non-founder"));
            //  Now enumerate through the grouping's sequence of StudentOptionEntry elements.
            foreach (StudentOptionEntry element in keyGroup)
                Console.WriteLine("id={0} : optionsCount={1} : dateAwarded={2:d}",
                  element.id, element.optionsCount, element.dateAwarded);
        }
    }
}
public class MyFounderNumberComparer : IEqualityComparer<int>
{
    public bool Equals(int x, int y)
    {
        return (isFounder(x) == isFounder(y));
    }

    public int GetHashCode(int i)
    {
        int f = 1;
        int nf = 100;
        return (isFounder(i) ? f.GetHashCode() : nf.GetHashCode());
    }

    public bool isFounder(int id)
    {
        return (id < 100);
    }
}
class StudentOptionEntry
{
    public int id;
    public long optionsCount;
    public DateTime dateAwarded;

    public static StudentOptionEntry[] GetStudentOptionEntries()
    {
        StudentOptionEntry[] empOptions = new StudentOptionEntry[] {
      new StudentOptionEntry {
        id = 1,
        optionsCount = 2,
        dateAwarded = DateTime.Parse("1990/12/31") },
      new StudentOptionEntry {
        id = 2,
        optionsCount = 3000,
        dateAwarded = DateTime.Parse("1992/06/30")  },
      new StudentOptionEntry {
        id = 2,
        optionsCount = 3000,
        dateAwarded = DateTime.Parse("1991/01/01")  },
      new StudentOptionEntry {
        id = 3,
        optionsCount = 5000,
        dateAwarded = DateTime.Parse("1997/09/30") },
      new StudentOptionEntry {
        id = 2,
        optionsCount = 3000,
        dateAwarded = DateTime.Parse("2000/04/01")  },
      new StudentOptionEntry {
        id = 3,
        optionsCount = 7500,
        dateAwarded = DateTime.Parse("1998/09/30") },
      new StudentOptionEntry {
        id = 3,
        optionsCount = 7500,
        dateAwarded = DateTime.Parse("1998/09/30") },
      new StudentOptionEntry {
        id = 4,
        optionsCount = 2456,
        dateAwarded = DateTime.Parse("1997/12/31") },
      new StudentOptionEntry {
        id = 101,
        optionsCount = 2,
        dateAwarded = DateTime.Parse("1998/12/31") }
    };

        return (empOptions);
    }
}

Result

Related Topic