Smartssolutions

Wednesday, October 5, 2011

How to sort an infinite collection

In one of my MSDN posts  they asked me how to sort an infinite collection and my response was to create a private custom collection object as follow:

public class MyArray<T> : ICollection<T>
 {
  private List<T> list;
  public delegate void CustomSortEventHandler(object sender, CustomSortEventArgs<T> customeventargs);
  public MyArray()
  {
   list = new List<T>();  
  }
  //You have to focus on that event that is triggered each time a new item is added
  private event CustomSortEventHandler sortEvent;
  public event CustomSortEventHandler SortEvent
  {
   add { sortEvent += SortEventHandler; OnSortEvent(); }
   remove { sortEvent -= SortEventHandler; }
  }
  public Comparison<T> Comparaison { get; set; }
  protected void OnSortEvent()
  {
   if (sortEvent!=null)
   {

    sortEvent(this, new CustomSortEventArgs<T>(Comparaison));
   }
  }
  //Here is the event handler that sorts data in the list
  protected void SortEventHandler(object sender, CustomSortEventArgs<T> args)
  {
   if (Comparaison==null)
   {
    list.Sort(); 
   }
   else
   {
    list.Sort(Comparaison);
   }
  }

  //Here is the indexed property
  public T this[int index]
  {
   get { return list[index]; }
   set { list.Add(value);/*You add an event handler at this point*/ this.SortEvent += SortEventHandler; }
  }
  
  public void Add(T item)
  {
   list.Add(item);
   //You add an event handler at this point
   this.SortEvent += SortEventHandler;
  }
  #region rest of the iCollection methods
  public void Clear()
  {
   list.Clear();
  }

  public bool Contains(T item)
  {
   return list.Contains(item);
  }

  public void CopyTo(T[] array, int arrayIndex)
  {
   throw new NotImplementedException();
  }

  public int Count
  {
   get { return list.Count; }
  }

  public bool IsReadOnly
  {
   get { return false; }
  }

  public bool Remove(T item)
  {
   throw new NotImplementedException();
  }

  public IEnumerator<T> GetEnumerator()
  {
   return list.GetEnumerator();
  }

  System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  {
   return list.GetEnumerator();
  }
  #endregion 
 }<br/><br/> public class CustomSortEventArgs<T> : EventArgs<br/> {<br/>  public Comparison<T> Comparaison { get; set; }<br/>  public CustomSortEventArgs(Comparison<T> comparaison)<br/>  {<br/>   Comparaison = comparaison;<br/>  }<br/> }




This first class will sort the entier collection when a new item arrived. This class can do the job for the litteral objects like the integer for example as well as  composed types.
To test this staff you just create a console application and add this class then in the main method  add this code

MyArray<int> myarray = new MyArray<int>();
 myarray.Add(-12);
 myarray.Add(23);
 myarray.Add(5);

 foreach (var item in myarray)
 {
 Console.WriteLine(item);
 }

and then fire the application. This is for the simple and litteral type. In the other hand and for the complex type I provided a delegate property which is named Comparaison in MyArray class. You just write your custom comparaison method and add it to that delegate. To explain more let consider this custom class

public class BerberKing
 {
 public string KingName { get; set; }
 public byte DateOfRule { get; set; }
 public override string ToString()
 {
 return string.Format(" Name {0}, Date of rule {1} BC",
 KingName,
 DateOfRule.ToString());
 }
 }


This class will represent the berber kings of Tamazgha(North Africa) and the deal will be sorting the collection of the berber kings according to their date of rule (Descending from the more older to the less older).
To do that you write down a custom method that compares the kings in the program class

static int ComparaisonMethod(BerberKing king1, BerberKing king2)
 {
 if (king1.DateOfRule>king2.DateOfRule)
 {
 return -1;
 }
 else if (king1.DateOfRule < king2.DateOfRule)
 {
 return 1;
 }
 else
  {
 return 0;
  }
 }


And then in the main method you add this code

static void Main(string[] args)
 {
 BerberKing gaia = new BerberKing { KingName = "GAIA", DateOfRule = 238 };
 BerberKing masnsn = new BerberKing { KingName = "MASNSN", DateOfRule = 206 };
 BerberKing missipsa = new BerberKing { KingName = "MISSIPSA", DateOfRule = 148 };

 MyArray<BerberKing> collection = new MyArray<BerberKing>();
 collection.Comparaison = new Comparison<BerberKing>(ComparaisonMethod);
 collection.Add(masnsn);
 collection.Add(gaia);
 collection.Add(missipsa);

 foreach (BerberKing item in collection)
 {
 Console.WriteLine(item.ToString());
 }

 

 Console.Read();
 }

No comments:

Post a Comment