andrew4582

EnumerableExtentions

Aug 20th, 2010
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.73 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. using System.Data.Linq.SqlClient;
  8.  
  9. namespace Core.Linq {
  10.  
  11.     //[DebuggerStepThrough]
  12.     public static class EnumerableExtentions {
  13.         //Func<TSource,bool> predicate
  14.         public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source,TSource valueIfDefault) {
  15.             TSource value = source.FirstOrDefault<TSource>();
  16.             if(value == null)
  17.                 return valueIfDefault;
  18.             else
  19.                 return value;
  20.         }
  21.         public static IEnumerable<TSource> Match<TSource>(this IEnumerable<TSource> first,IEnumerable<TSource> second) {
  22.             List<TSource> matchedList = new List<TSource>();
  23.             foreach(TSource item in second) {
  24.                 if(first.Contains<TSource>(item))
  25.                     matchedList.Add(item);
  26.             }
  27.             return matchedList.AsEnumerable();
  28.         }
  29.  
  30.         public static IEnumerable<T> IIf<T>(this IEnumerable<T> source,Func<T,bool> predicate,T resultIfFalse) {
  31.             var matched = source.Where(predicate);
  32.             if(matched.Count() > 0)
  33.                 return matched;
  34.             else {
  35.                 List<T> result = new List<T>();
  36.                 result.Add(resultIfFalse);
  37.                 return result.AsEnumerable();
  38.             }
  39.         }
  40.         public static IEnumerable<object> IIf<T>(this IEnumerable<T> source,Func<T,bool> predicate,Func<T,object> selectorIfFalse) {
  41.             var matched = source.Where(predicate);
  42.             if(matched.Count() > 0)
  43.                 return matched.Cast<object>().AsEnumerable();
  44.             else {
  45.                 return source.Select(selectorIfFalse);
  46.             }
  47.         }
  48.         public static IEnumerable<T> Random<T>(this IEnumerable<T> source) {
  49.             return Random<T>(source,Environment.TickCount);
  50.         }
  51.         public static IEnumerable<T> Random<T>(this IEnumerable<T> source,int seed) {
  52.             Random rnd = new Random(seed);
  53.            
  54.             T[] arr = source.ToArray();
  55.             T[] arrto = new T[arr.Length];
  56.  
  57.             int sourceLength = arr.Length;
  58.            
  59.             for(int i = 0;i < sourceLength;i++) {
  60.                 arrto[i] = arr[rnd.Next(sourceLength - 1)];
  61.             }
  62.             return arrto;
  63.         }
  64.  
  65.         public static IEnumerable<T> Each<T>(this IEnumerable<T> source,Action<T> fEachItem) {
  66.             foreach(var item in source)
  67.                 fEachItem(item);
  68.             return source;
  69.         }
  70.         public static IEnumerable<T> Edit<T>(this IEnumerable<T> source,Func<T,T> fEdit) {
  71.             T[] sourceArray = source.ToArray();
  72.             for(int i = 0;i < sourceArray.Length;i++) {
  73.                 sourceArray[i] = fEdit(sourceArray[i]);
  74.             }
  75.             return sourceArray.AsEnumerable();
  76.         }
  77.  
  78.         public static IQueryable<T> Like<T>(this IQueryable<T> source,string propertyName,string keyword) {
  79.            
  80.             var type = typeof(T);
  81.             var property = type.GetProperty(propertyName);
  82.             var parameter = Expression.Parameter(type,"p");
  83.             var propertyAccess = Expression.MakeMemberAccess(parameter,property);
  84.             var constant = Expression.Constant("%" + keyword + "%");
  85.             MethodCallExpression methodExp = Expression.Call(null,typeof(SqlMethods).GetMethod("Like",new Type[] { typeof(string),typeof(string) }),propertyAccess,constant);
  86.             Expression<Func<T,bool>> lambda = Expression.Lambda<Func<T,bool>>(methodExp,parameter);
  87.             return source.Where(lambda);
  88.         }
  89.         public static IQueryable<T> Where<T>(this IQueryable<T> source,string predicate,params object[] values) {
  90.             if(source == null)
  91.                 throw new ArgumentNullException("source");
  92.             if(predicate == null)
  93.                 throw new ArgumentNullException("predicate");
  94.  
  95.             LambdaExpression lambda = System.Linq.Dynamic.DynamicExpression.ParseLambda(source.ElementType,typeof(bool),predicate,values);
  96.  
  97.             return source.Provider.CreateQuery<T>(
  98.                 Expression.Call(
  99.                     typeof(Queryable),"Where",
  100.                     new Type[] { source.ElementType },
  101.                     source.Expression,Expression.Quote(lambda)));
  102.         }
  103.         public static IQueryable<T> OrderByt<T>(this IQueryable<T> source,string propertyName,bool asc) {
  104.             var type = typeof(T);
  105.             string methodName = asc ? "OrderBy" : "OrderByDescending";
  106.             var property = type.GetProperty(propertyName);
  107.             var parameter = Expression.Parameter(type,"p");
  108.             var propertyAccess = Expression.MakeMemberAccess(parameter,property);
  109.             var orderByExp = Expression.Lambda(propertyAccess,parameter);
  110.             MethodCallExpression resultExp = Expression.Call(typeof(Queryable),methodName,new Type[] { type,property.PropertyType },source.Expression,Expression.Quote(orderByExp));
  111.             return source.Provider.CreateQuery<T>(resultExp);
  112.         }
  113.  
  114.         #region OrderBy & OrderByName
  115.  
  116.         public static IOrderedQueryable<TSource> OrderByName<TSource>(this IQueryable<TSource> source,string propertyName) {
  117.             return OrderBy(source,propertyName);
  118.         }
  119.         public static IOrderedQueryable<TSource> OrderByDescendingName<TSource>(this IQueryable<TSource> source,string propertyName) {
  120.             return OrderByDescending(source,propertyName);
  121.         }
  122.         public static IOrderedQueryable<TSource> OrderByName<TSource>(this IQueryable<TSource> source,string propertyName,bool ascending) {
  123.             if(ascending)
  124.                 return OrderByName(source,propertyName);
  125.             else
  126.                 return OrderByDescendingName(source,propertyName);
  127.         }
  128.  
  129.         public static IQueryable<TSource> OrderByName<TSource>(this IEnumerable<TSource> source,string propertyName) {
  130.             return OrderBy(source.AsQueryable(),propertyName);
  131.         }
  132.         public static IOrderedQueryable<TSource> OrderByDescendingName<TSource>(this IEnumerable<TSource> source,string propertyName) {
  133.             return OrderByDescending(source.AsQueryable(),propertyName);
  134.         }
  135.         public static IOrderedQueryable<TSource> OrderByName<TSource>(this IEnumerable<TSource> source,string propertyName,bool ascending) {
  136.             if(ascending)
  137.                 return OrderByName(source.AsQueryable(),propertyName);
  138.             else
  139.                 return OrderByDescendingName(source.AsQueryable(),propertyName);
  140.         }
  141.  
  142.         public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source,string property) {
  143.             return ApplyOrder<T>(source,property,"OrderBy");
  144.         }
  145.         public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source,string property) {
  146.             return ApplyOrder<T>(source,property,"OrderByDescending");
  147.         }
  148.         public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source,string property) {
  149.             return ApplyOrder<T>(source,property,"ThenBy");
  150.         }
  151.         public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source,string property) {
  152.             return ApplyOrder<T>(source,property,"ThenByDescending");
  153.         }
  154.         static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source,string property,string methodName) {
  155.             string[] props = property.Split('.');
  156.             Type type = typeof(T);
  157.             ParameterExpression arg = Expression.Parameter(type,"x");
  158.             Expression expr = arg;
  159.             foreach(string prop in props) {
  160.                 // use reflection (not ComponentModel) to mirror LINQ
  161.                 PropertyInfo pi = type.GetProperty(prop);
  162.                 if(pi != null) {
  163.                     expr = Expression.Property(expr,pi);
  164.                     type = pi.PropertyType;
  165.                 }
  166.             }
  167.             Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T),type);
  168.             LambdaExpression lambda = Expression.Lambda(delegateType,expr,arg);
  169.  
  170.             object result = typeof(Queryable).GetMethods().Single(
  171.                     method => method.Name == methodName
  172.                             && method.IsGenericMethodDefinition
  173.                             && method.GetGenericArguments().Length == 2
  174.                             && method.GetParameters().Length == 2)
  175.                     .MakeGenericMethod(typeof(T),type)
  176.                     .Invoke(null,new object[] { source,lambda });
  177.             return (IOrderedQueryable<T>)result;
  178.         }
  179.         #endregion
  180.  
  181.         #region Between
  182.         public static IEnumerable<T> Between<T>(this IEnumerable<T> source,Func<T,bool> endPredicate) {
  183.             if(source == null)
  184.                 throw Throw.ArgumentNull("source");
  185.             if(endPredicate == null)
  186.                 throw Throw.ArgumentNull("endPredicate");
  187.             return BetweenIterator<T>(source,b => true,endPredicate);
  188.         }
  189.         public static IEnumerable<T> Between<T>(this IEnumerable<T> source,Func<T,bool> startPredicate,Func<T,bool> endPredicate) {
  190.             if(source == null)
  191.                 throw Throw.ArgumentNull("source");
  192.             if(startPredicate == null)
  193.                 throw Throw.ArgumentNull("startPredicate");
  194.             if(endPredicate == null)
  195.                 throw Throw.ArgumentNull("endPredicate");
  196.             return BetweenIterator<T>(source,startPredicate,endPredicate);
  197.         }
  198.         public static IEnumerable<T> Between<T>(this IEnumerable<T> source,T start,T end) where T:IComparable {
  199.             bool includeStartEnd = false;
  200.             return Between<T>(source,start,end,includeStartEnd);
  201.         }
  202.         public static IEnumerable<T> Between<T>(this IEnumerable<T> source,T start,T end,bool includeStartEnd) where T:IComparable {
  203.  
  204.             if(source == null)
  205.                 throw Throw.ArgumentNull("source");
  206.             if(start == null)
  207.                 throw Throw.ArgumentNull("start");
  208.             if(end == null)
  209.                 throw Throw.ArgumentNull("end");
  210.  
  211.             bool foundStart = false;
  212.             bool foundEnd = false;
  213.  
  214.             foreach(T element in source) {
  215.                 if(foundEnd) {
  216.                     yield break;
  217.                 }
  218.                 else {
  219.                     if(element.Equals(start)) {
  220.                         foundStart = true;
  221.                         if(includeStartEnd)
  222.                             yield return element;
  223.                         else
  224.                             continue;
  225.                     }
  226.                     else {
  227.                         if(foundStart) {
  228.                             if(element.Equals(end)) {
  229.                                 foundEnd = true;
  230.                                 if(includeStartEnd)
  231.                                     yield return element;
  232.                                 else
  233.                                     continue;
  234.                             }
  235.                             else
  236.                                 yield return element;
  237.                         }
  238.                     }
  239.                 }
  240.             }
  241.         }
  242.         static IEnumerable<T> BetweenIterator<T>(IEnumerable<T> source,Func<T,bool> startPredicate,Func<T,bool> endPredicate) {
  243.             bool foundStart = false;
  244.             foreach(T element in source) {
  245.                 if(startPredicate(element))
  246.                     foundStart = true;
  247.                 if(foundStart)
  248.                     if(!endPredicate(element))
  249.                         yield return element;
  250.                     else
  251.                         yield break;
  252.             }
  253.         }
  254.  
  255.         #endregion
  256.     }
  257. }
Advertisement
Add Comment
Please, Sign In to add comment