tomlev

API to compare items by the specified key(s)

Mar 13th, 2013
46
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. public class ByKeyComparer<T, TKey> : IComparer<T>
  2. {
  3.     private readonly Func<T, TKey> _keySelector;
  4.     private readonly IComparer<TKey> _keyComparer;
  5.  
  6.     public ByKeyComparer(Func<T, TKey> keySelector, IComparer<TKey> keyComparer = null)
  7.     {
  8.         if (keySelector == null) throw new ArgumentNullException("keySelector");
  9.         _keySelector = keySelector;
  10.         _keyComparer = keyComparer ?? Comparer<TKey>.Default;
  11.     }
  12.  
  13.     public int Compare(T x, T y)
  14.     {
  15.         return _keyComparer.Compare(_keySelector(x), _keySelector(y));
  16.     }
  17. }
  18.  
  19. public class CompositeComparer<T> : IComparer<T>
  20. {
  21.     private readonly IEnumerable<IComparer<T>> _comparers;
  22.  
  23.     public CompositeComparer(IEnumerable<IComparer<T>> comparers)
  24.     {
  25.         if (comparers == null) throw new ArgumentNullException("comparers");
  26.         _comparers = comparers.ToList().AsReadOnly();
  27.     }
  28.    
  29.     public IEnumerable<IComparer<T>> Comparers
  30.     {
  31.         get { return _comparers; }
  32.     }
  33.  
  34.     public CompositeComparer(params IComparer<T>[] comparers)
  35.         : this((IEnumerable<IComparer<T>>)comparers)
  36.     {
  37.     }
  38.  
  39.     public int Compare(T x, T y)
  40.     {
  41.         foreach (var comparer in _comparers)
  42.         {
  43.             int result = comparer.Compare(x, y);
  44.             if (result != 0)
  45.                 return result;
  46.         }
  47.         return 0;
  48.     }
  49. }
  50.  
  51. public class ReverseComparer<T> : IComparer<T>
  52. {
  53.     private readonly IComparer<T> _comparer;
  54.  
  55.     public ReverseComparer(IComparer<T> comparer)
  56.     {
  57.         _comparer = comparer;
  58.     }
  59.    
  60.     public int Compare(T x, T y)
  61.     {
  62.         return _comparer.Compare(y, x);
  63.     }
  64. }
  65.  
  66. public static class ByKeyComparer<T>
  67. {
  68.     public static IComparer<T> CompareBy<TKey>(Func<T, TKey> keySelector, IComparer<TKey> keyComparer = null)
  69.     {
  70.         return new ByKeyComparer<T, TKey>(keySelector, keyComparer);
  71.     }
  72.    
  73.     public static IComparer<T> CompareByDescending<TKey>(Func<T, TKey> keySelector, IComparer<TKey> keyComparer = null)
  74.     {
  75.         return new ByKeyComparer<T, TKey>(keySelector, keyComparer).Reverse();
  76.     }
  77. }
  78.  
  79. public static class ComparerExtensions
  80. {
  81.     public static IComparer<T> Reverse<T>(this IComparer<T> comparer)
  82.     {
  83.         return new ReverseComparer<T>(comparer);
  84.     }
  85.    
  86.     public static IComparer<T> ThenBy<T>(this IComparer<T> comparer, IComparer<T> otherComparer)
  87.     {
  88.         var composite = comparer as CompositeComparer<T>;
  89.         if (composite != null)
  90.             return new CompositeComparer<T>(composite.Comparers.Concat(new[] { otherComparer }));
  91.         return new CompositeComparer<T>(comparer, otherComparer);
  92.     }
  93.  
  94.     public static IComparer<T> ThenBy<T, TKey>(this IComparer<T> comparer, Func<T, TKey> keySelector, IComparer<TKey> keyComparer = null)
  95.     {
  96.         return comparer.ThenBy(ByKeyComparer<T>.CompareBy(keySelector, keyComparer));
  97.     }
  98.    
  99.     public static IComparer<T> ThenByDescending<T, TKey>(this IComparer<T> comparer, Func<T, TKey> keySelector, IComparer<TKey> keyComparer = null)
  100.     {
  101.         return comparer.ThenBy(ByKeyComparer<T>.CompareByDescending(keySelector, keyComparer));
  102.     }
  103. }
RAW Paste Data