using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
namespace Apewer
{
/// 集合的实用工具。
public static class CollectionUtility
{
#region 判断
/// 判断集合为空。
public static bool IsEmpty(IEnumerable objects)
{
if (objects == null) return true;
if (objects is T[]) return ((T[])objects).LongLength < 1L;
if (objects is ICollection) return ((ICollection)objects).Count < 1;
foreach (var item in objects) return false;
return true;
}
/// 判断集合存在元素。
public static bool NotEmpty(IEnumerable objects)
{
if (objects == null) return false;
if (objects is T[]) return ((T[])objects).LongLength > 0L;
if (objects is ICollection) return ((ICollection)objects).Count > 0;
foreach (var item in objects) return true;
return false;
}
/// 获取集合中元素的数量。
public static int Count(IEnumerable objects)
{
if (objects == null) return 0;
var array = objects as T[];
if (array != null) return array.Length;
var collection = objects as ICollection;
if (collection != null) return collection.Count;
var count = 0;
foreach (var cell in objects) count++;
return count;
}
/// 检查集合是否包含 item。
public static bool Contains(IEnumerable objects, T cell)
{
if (objects == null) return false;
// objects 实现了含有 Contains 方法的接口。
if (objects is ICollection) return ((ICollection)objects).Contains(cell);
// cell 无效。
if (cell == null)
{
foreach (var i in objects)
{
if (i == null) return true;
}
return false;
}
// cell 有效,进行默认比较。
var comparer = EqualityComparer.Default;
foreach (var i in objects)
{
if (comparer.Equals(i, cell)) return true;
}
return false;
}
/// 获取 item 在集合中的偏移位置,不存在时返回 -1。
public static int IndexOf(IEnumerable objects, T item)
{
if (objects == null) return -1;
if (objects is IList list) return list.IndexOf(item);
if (item == null)
{
if (objects is T[] array)
{
var length = array.Length;
for (var i = 0; i < length; i++)
{
if (array[i] == null) return i;
}
return -1;
}
var index = 0;
foreach (var obj in objects)
{
if (obj == null) return index;
index++;
}
return -1;
}
else
{
var comparer = EqualityComparer.Default;
if (objects is T[] array)
{
var length = array.Length;
for (var i = 0; i < length; i++)
{
if (comparer.Equals(item, array[i])) return i;
}
return -1;
}
var index = 0;
foreach (var obj in objects)
{
if (comparer.Equals(item, obj)) return index;
index++;
}
return -1;
}
}
#endregion
#region 类型转换
/// 转换模型类型。
public static TDst[] As(this TSrc[] array) where TDst : class
{
if (array == null) return null;
var count = array.Length;
var output = new TDst[count];
for (var i = 0; i < count; i++)
{
var item = array[i];
if (item == null) continue;
output[i] = item as TDst;
}
return output;
}
/// 转换模型类型。
public static TDst[] As(this TSrc[] array, Func convert)
{
if (convert == null) throw new ArgumentNullException(nameof(convert));
if (array == null) return null;
var count = array.Length;
var output = new TDst[count];
for (var i = 0; i < count; i++)
{
var item = array[i];
if (item == null) continue;
output[i] = convert(item);
}
return output;
}
/// 安全转换为 List<> 对象。可指定排除 NULL 值元素。
public static List List(IEnumerable objects, bool excludeNull = false)
{
if (objects == null) return new List();
var list = new List();
var collection = objects as ICollection;
if (collection != null)
{
list.AddRange(objects);
}
else
{
var group = 1024;
var added = 0;
var capacity = 0;
if (objects != null)
{
foreach (var item in objects)
{
if (excludeNull && item == null) continue;
if (added == capacity)
{
capacity += group;
list.Capacity = capacity;
}
list.Add(item);
added += 1;
}
}
list.Capacity = added;
}
return list;
}
/// 安全转换为 <>[] 对象。可指定排除 NULL 值元素。
public static T[] Array(IEnumerable objects, bool excludeNull = false)
{
if (objects == null) return new T[0];
if (objects is T[]) return (T[])objects;
var collection = objects as ICollection;
if (collection != null)
{
var array = new T[collection.Count];
collection.CopyTo(array, 0);
return array;
}
else
{
var group = 1024;
var array = new T[group];
var added = 0;
var capacity = 0;
foreach (var item in objects)
{
if (excludeNull && item == null) continue;
if (added == capacity)
{
capacity += group;
var temp = new T[capacity];
System.Array.Copy(array, 0, temp, 0, added);
array = temp;
}
array[added] = item;
added += 1;
}
if (added < 1 || added == capacity) return array;
var collapsed = new T[added];
System.Array.Copy(array, 0, collapsed, 0, added);
return collapsed;
}
}
/// 生成 StringPairs 对象实例为副本。
public static StringPairs StringPairs(NameValueCollection @this) => Apewer.StringPairs.From(@this);
/// 转换集合为数组。
///
///
public static Dictionary Dictionary(NameValueCollection collection)
{
if (collection == null) return null;
var count = collection.Count;
var dict = new Dictionary();
for (var i = 0; i < count; i++)
{
var key = collection.GetKey(i);
var values = collection.GetValues(i);
dict.Add(key, values);
}
return dict;
}
/// 转换集合为字典。
/// 字典 Key 的类型。
/// 字典 Value 的类型。
/// 要转换的集合。
/// 根据元素获取 Key 的函数。
///
public static Dictionary Dictionary(IEnumerable items, Func key)
{
if (items == null) throw new ArgumentNullException(nameof(items));
if (key == null) throw new ArgumentNullException(nameof(key));
var dict = new Dictionary();
foreach (var i in items)
{
if (i == null) continue;
var k = key(i);
if (k.IsNull()) continue;
if (dict.ContainsKey(k)) continue;
dict.Add(k, i);
}
return dict;
}
#endregion
#region 修改集合
/// 添加多个元素。
public static void Add(List list, params T[] items)
{
if (list != null && items != null) list.AddRange(items);
}
/// 添加多个元素。
public static IList Add(IList list, IEnumerable items)
{
if (list != null && items != null)
{
foreach (var item in items) list.Add(item);
}
return list;
}
/// 添加元素。
public static bool Add(IList> list, TKey key, TValue value)
{
if (list == null) return false;
list.Add(new KeyValuePair(key, value));
return true;
}
/// 对元素去重,且去除 NULL 值。
public static T[] Distinct(this IEnumerable items)
{
if (items == null) throw new ArgumentNullException(nameof(items));
var count = Count(items);
var added = 0;
var array = new T[count];
var comparer = EqualityComparer.Default;
foreach (var item in items)
{
if (item == null) continue;
var contains = false;
foreach (var i in array)
{
if (comparer.Equals(i, item))
{
contains = true;
break;
}
}
if (contains) continue;
array[added] = item;
added++;
}
if (added < count)
{
var temp = new T[added];
System.Array.Copy(array, 0, temp, 0, added);
array = temp;
}
return array;
}
/// 清理集合,去除 NULL 值。
public static T[] Vacuum(this IEnumerable items) => FindAll(items, x => x != null);
/// 获取可枚举集合的部分元素。
/// 集合元素的类型。
/// 原集合。
/// 在集合前段要跳过的元素数量。
/// 要获取的元素数量,指定为负数时不限元素数量。
/// 填充器,获取范围超出原集合的部分,使用此方法填充元素;此函数默认返回 的默认值。
/// 数量符合 count 的数组。
public static T[] Slice(IEnumerable objects, int skip = 0, int count = -1, Func stuffer = null)
{
if (count == 0) return new T[0];
var ab = new ArrayBuilder();
var added = 0;
if (skip < 0)
{
var end = 0 - skip;
for (var i = 0; i < end; i++)
{
ab.Add(stuffer == null ? default : stuffer());
added++;
if (count > 0 && added == count) return ab.Export();
}
}
if (objects != null)
{
var offset = 0;
foreach (var item in objects)
{
if (offset < skip)
{
offset++;
continue;
}
ab.Add(item);
added++;
offset++;
if (count > 0 && added == count) return ab.Export();
}
}
while (added < count)
{
ab.Add(stuffer == null ? default : stuffer());
added++;
}
return ab.Export();
}
/// 在数组尾部增加元素,生成新数组,不修改原数组。
/// 增加元素后的新数组。
public static T[] Push(this T[] array, T item)
{
if (array == null) return new T[] { item };
var length = array.Length;
var newArray = new T[length + 1];
if (length > 0) System.Array.Copy(array, 0, newArray, 0, length);
newArray[length] = item;
return newArray;
}
/// 在数组尾部增加元素,生成新数组,不修改原数组。
/// 增加元素后的新数组。
public static T[] Push(this T[] array, T[] items)
{
if (array == null) return items ?? new T[0];
if (items == null)
{
var result = new T[array.Length];
array.CopyTo(result, 0);
return result;
}
else
{
var length1 = array.Length;
var length2 = items.Length;
var result = new T[length1 + length2];
if (length1 > 0) System.Array.Copy(array, 0, result, 0, length1);
if (length2 > 0) System.Array.Copy(items, 0, result, length1, length2);
return result;
}
}
/// 在数组头部增加元素,生成新数组,不修改原数组。
/// 增加元素后的新数组。
public static T[] Unshift(this T[] array, T item)
{
if (array == null) return new T[] { item };
var length = array.Length;
var newArray = new T[length + 1];
newArray[0] = item;
if (length > 0) System.Array.Copy(array, 0, newArray, 1, length);
return newArray;
}
/// 在数组头部增加元素,生成新数组,不修改原数组。
/// 增加元素后的新数组。
public static T[] Unshift(this T[] array, T[] items)
{
if (array == null) return items ?? new T[0];
if (items == null)
{
var result = new T[array.Length];
array.CopyTo(result, 0);
return result;
}
else
{
var length1 = array.Length;
var length2 = items.Length;
var result = new T[length1 + length2];
if (length2 > 0) System.Array.Copy(items, 0, result, 0, length2);
if (length1 > 0) System.Array.Copy(array, 0, result, length2, length1);
return result;
}
}
#endregion
#region 排序
/// 对列表中的元素排序。
public static List Sort(List list, Func comparison)
{
if (list == null) return null;
if (comparison == null) return list;
list.Sort(new Comparison(comparison));
return list;
}
/// 对数组排序。
///
public static T[] Sort(T[] array, Func comparison)
{
if (array == null) return array;
if (comparison == null) return array;
System.Array.Sort(array, new Comparison(comparison));
return array;
}
/// 获取集合中的第一个元素。可指定失败时的默认返回值。
public static T First(IEnumerable collection, T failed = default(T))
{
if (collection == null) return failed;
var array = collection as T[];
if (array != null) return array.Length > 0 ? array[0] : failed;
var list = collection as IList;
if (list != null) return list.Count > 0 ? list[0] : failed;
foreach (var item in collection) return item;
return failed;
}
/// 获取集合中的最后一个元素。可指定失败时的默认返回值。
public static T Last(IEnumerable collection, T failed = default(T))
{
if (collection == null) return failed;
var array = collection as T[];
if (array != null) return array.Length > 0 ? array[array.Length - 1] : failed;
var list = collection as IList;
if (list != null) return list.Count > 0 ? list[list.Count - 1] : failed;
var value = failed;
foreach (var item in collection) value = item;
return value;
}
/// 对数组升序排序。
///
public static T[] Ascend(T[] array) where T : IComparable
{
if (array == null) return null;
array.Sort((a, b) => a.CompareTo(b));
return array;
}
/// 对数组升序排序。
///
public static List Ascend(List list) where T : IComparable
{
if (list == null) return null;
list.Sort((a, b) => a.CompareTo(b));
return list;
}
/// 对数组升序排序。
///
public static void Ascend(T[] array, Func func) where TProp : IComparable
{
if (array != null && func != null) Sort(array, (a, b) => func(a).CompareTo(func(b)));
}
/// 对数组降序排序。
///
public static T[] Descend(T[] array) where T : IComparable
{
if (array == null) return array;
Sort(array, (a, b) => 0 - a.CompareTo(b));
return array;
}
/// 对数组降序排序。
///
public static List Descend(List list) where T : IComparable
{
if (list == null) return null;
list.Sort((a, b) => -a.CompareTo(b));
return list;
}
/// 对数组降序排序。
///
public static void Descend(T[] array, Func func) where TProp : IComparable
{
if (array != null && func != null) Sort(array, (a, b) => 0 - func(a).CompareTo(func(b)));
}
/// 对字典中的键排序。
public static Dictionary SortKey(Dictionary dict, Func comparison)
{
if (dict == null) return null;
if (comparison == null) return null;
var list = new List>(dict);
list.Sort(new Comparison>((a, b) => comparison(a.Key, b.Key)));
dict.Clear();
foreach (var item in list) dict.Add(item.Key, item.Value);
return dict;
}
/// 对字典中的键排序。
public static Dictionary SortKey(Dictionary @this) where TKey : IComparable
{
return SortKey(@this, (a, b) => a.CompareTo(b));
}
/// 对字典中的值排序。
public static Dictionary SortValue(Dictionary dict, Func comparison)
{
if (dict == null) return null;
if (comparison == null) return dict;
var list = new List>(dict);
list.Sort(new Comparison>((a, b) => comparison(a.Value, b.Value)));
dict.Clear();
foreach (var item in list) dict.Add(item.Key, item.Value);
return dict;
}
/// 对字典中的值排序。
public static Dictionary SortValue(Dictionary @this) where TValue : IComparable
{
return SortValue(@this, (a, b) => a.CompareTo(b));
}
#endregion
#region params
internal static object[] ParseParams(object cells)
{
var parsed = new ArrayBuilder