additional collection extensions
This commit is contained in:
parent
93dce4df90
commit
191aaa20cf
@ -7,11 +7,18 @@ using System.Data;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
|
||||
namespace BinaryDad.Extensions
|
||||
{
|
||||
public static class CollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds an item to the <see cref="ICollection{T}"/>, replacing it if it already exists
|
||||
/// </summary>
|
||||
/// <typeparam name="TItem"></typeparam>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="item"></param>
|
||||
public static void AddReplace<TItem, TProperty>(this ICollection<TItem> items, TItem item, Func<TItem, TProperty> matchingProperty) where TItem : class where TProperty : IComparable
|
||||
{
|
||||
var existing = items.FirstOrDefault(i => matchingProperty(i).Equals(matchingProperty(item)));
|
||||
@ -39,6 +46,21 @@ namespace BinaryDad.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Groups a set of items into batches of a given batch size
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="batchSize"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<ICollection<T>> Batch<T>(this IEnumerable<T> items, int batchSize)
|
||||
{
|
||||
return items.Select((Item, Index) => new { Item, Index })
|
||||
.GroupBy(x => x.Index / batchSize)
|
||||
.Select(x => x.Select(t => t.Item).ToList())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a distinct list of elements using the first-matched item on a specific property
|
||||
/// </summary>
|
||||
@ -69,6 +91,16 @@ namespace BinaryDad.Extensions
|
||||
|
||||
#region ToDataTable
|
||||
|
||||
/// <summary>
|
||||
/// Converts a typed collection into a <see cref="DataTable"/>. This method excludes the column if <see cref="NotMappedAttribute"/> is bound to a property.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="useColumnAttributeName">Specifies whether the data column should use the name from <see cref="ColumnAttribute"/></param>, if bound to a property.
|
||||
/// <param name="tableName"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ToDataTable(this IEnumerable collection, bool useColumnAttributeName = false, string tableName = null) => ToDataTable(collection, null, useColumnAttributeName, tableName);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a typed collection into a <see cref="DataTable"/>. This method excludes the column if <see cref="NotMappedAttribute"/> is bound to a property.
|
||||
/// </summary>
|
||||
@ -78,7 +110,19 @@ namespace BinaryDad.Extensions
|
||||
/// <param name="useColumnAttributeName">Specifies whether the data column should use the name from <see cref="ColumnAttribute"/></param>, if bound to a property.
|
||||
/// <param name="tableName"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ToDataTable(this IEnumerable collection, Func<PropertyInfo, string> columnNameModifier, bool useColumnAttributeName = false, string tableName = null)
|
||||
public static DataTable ToDataTable(this IEnumerable collection, Func<PropertyInfo, string> columnNameModifier, bool useColumnAttributeName = false, string tableName = null) => ToDataTable(collection, columnNameModifier, null, useColumnAttributeName, tableName);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a typed collection into a <see cref="DataTable"/>. This method excludes the column if <see cref="NotMappedAttribute"/> is bound to a property.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="columnNameModifier">If a non-null string is returned, the column name is overridden</param>
|
||||
/// <param name="columnIncludeModifier">If a condition is supplied, only columns matching the condition will be included</param>
|
||||
/// <param name="useColumnAttributeName">Specifies whether the data column should use the name from <see cref="ColumnAttribute"/></param>, if bound to a property.
|
||||
/// <param name="tableName"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ToDataTable(this IEnumerable collection, Func<PropertyInfo, string> columnNameModifier, Func<PropertyInfo, bool> columnIncludeModifier, bool useColumnAttributeName = false, string tableName = null)
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
@ -116,10 +160,25 @@ namespace BinaryDad.Extensions
|
||||
|
||||
var propertyInfo = type
|
||||
.GetProperties()
|
||||
.Where(p => !p.HasCustomAttribute<NotMappedAttribute>())
|
||||
.Where(p =>
|
||||
{
|
||||
// automatically ignore [NotMapped] attribute properties
|
||||
if (p.HasCustomAttribute<NotMappedAttribute>())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// allow for custom column inclusion
|
||||
if (columnIncludeModifier != null)
|
||||
{
|
||||
return columnIncludeModifier.Invoke(p);
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.Select(p =>
|
||||
{
|
||||
string columnName = p.Name;
|
||||
var columnName = p.Name;
|
||||
string columnTypeName = null;
|
||||
|
||||
// set column name to be either the property name
|
||||
@ -206,6 +265,13 @@ namespace BinaryDad.Extensions
|
||||
|
||||
#region Join
|
||||
|
||||
/// <summary>
|
||||
/// Serializes a collection of objects (wrapper for <see cref="string.Join{T}(string, IEnumerable{T})"/>)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <returns></returns>
|
||||
public static string Join<T>(this IEnumerable<T> items, string separator = "") where T : IComparable
|
||||
{
|
||||
if (items == null)
|
||||
@ -221,6 +287,15 @@ namespace BinaryDad.Extensions
|
||||
return string.Join(separator, items.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes a collection of objects with a custom property selector (wrapper for <see cref="string.Join{T}(string, IEnumerable{T})"/>)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TSelector"></typeparam>
|
||||
/// <param name="items"></param>
|
||||
/// <param name="selector"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <returns></returns>
|
||||
public static string Join<T, TSelector>(this IEnumerable<T> items, Func<T, TSelector> selector, string separator = "") where TSelector : IComparable => Join(items.Select(selector), separator);
|
||||
|
||||
/// <summary>
|
||||
@ -537,7 +612,48 @@ namespace BinaryDad.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<KeyValuePair<TKey, TSource>> source, IEqualityComparer<TKey> comparer = null) => source.ToDictionary(k => k.Key, v => v.Value, comparer);
|
||||
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<KeyValuePair<TKey, TSource>> source) => source.ToDictionary(k => k.Key, v => v.Value);
|
||||
|
||||
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<KeyValuePair<TKey, TSource>> source, IEqualityComparer<TKey> comparer) => source.ToDictionary(k => k.Key, v => v.Value, comparer);
|
||||
|
||||
public static void Add<TKey, TValue>(this IDictionary<TKey, TValue> source, KeyValuePair<TKey, TValue> value) => source.Add(value.Key, value.Value);
|
||||
|
||||
public static T To<T>(this IDictionary<string, object> source) where T : class, new()
|
||||
{
|
||||
var instance = new T();
|
||||
|
||||
var properties = typeof(T).GetProperties();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var propertyName = property.Name;
|
||||
|
||||
if (source.ContainsKey(propertyName))
|
||||
{
|
||||
property.SetValue(instance, source[propertyName]);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a query string using a dictionary
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToQueryString<T>(this IEnumerable<KeyValuePair<string, T>> source) where T : IConvertible
|
||||
{
|
||||
// allows us to get a HttpValueCollection which provides proper serialiation/encoding
|
||||
var collection = HttpUtility.ParseQueryString(string.Empty);
|
||||
|
||||
foreach (var pair in source)
|
||||
{
|
||||
collection.Add(pair.Key, pair.Value?.ToString());
|
||||
}
|
||||
|
||||
return collection.ToString();
|
||||
}
|
||||
|
||||
#region Replace
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user