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;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
namespace BinaryDad.Extensions
|
namespace BinaryDad.Extensions
|
||||||
{
|
{
|
||||||
public static class CollectionExtensions
|
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
|
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)));
|
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>
|
/// <summary>
|
||||||
/// Returns a distinct list of elements using the first-matched item on a specific property
|
/// Returns a distinct list of elements using the first-matched item on a specific property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -69,6 +91,16 @@ namespace BinaryDad.Extensions
|
|||||||
|
|
||||||
#region ToDataTable
|
#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>
|
/// <summary>
|
||||||
/// Converts a typed collection into a <see cref="DataTable"/>. This method excludes the column if <see cref="NotMappedAttribute"/> is bound to a property.
|
/// Converts a typed collection into a <see cref="DataTable"/>. This method excludes the column if <see cref="NotMappedAttribute"/> is bound to a property.
|
||||||
/// </summary>
|
/// </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="useColumnAttributeName">Specifies whether the data column should use the name from <see cref="ColumnAttribute"/></param>, if bound to a property.
|
||||||
/// <param name="tableName"></param>
|
/// <param name="tableName"></param>
|
||||||
/// <returns></returns>
|
/// <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)
|
if (collection == null)
|
||||||
{
|
{
|
||||||
@ -116,10 +160,25 @@ namespace BinaryDad.Extensions
|
|||||||
|
|
||||||
var propertyInfo = type
|
var propertyInfo = type
|
||||||
.GetProperties()
|
.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 =>
|
.Select(p =>
|
||||||
{
|
{
|
||||||
string columnName = p.Name;
|
var columnName = p.Name;
|
||||||
string columnTypeName = null;
|
string columnTypeName = null;
|
||||||
|
|
||||||
// set column name to be either the property name
|
// set column name to be either the property name
|
||||||
@ -206,6 +265,13 @@ namespace BinaryDad.Extensions
|
|||||||
|
|
||||||
#region Join
|
#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
|
public static string Join<T>(this IEnumerable<T> items, string separator = "") where T : IComparable
|
||||||
{
|
{
|
||||||
if (items == null)
|
if (items == null)
|
||||||
@ -221,6 +287,15 @@ namespace BinaryDad.Extensions
|
|||||||
return string.Join(separator, items.ToArray());
|
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);
|
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>
|
/// <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
|
#region Replace
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user