using System; using System.Collections; using System.Collections.Generic; using System.Text; namespace Apewer.Internals { internal class CollectionHelper { #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 List Ascend(List list) where T : IComparable { if (list == null) return null; list.Sort((a, b) => a.CompareTo(b)); return list; } 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 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 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; } #endregion 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; } // 安全转换为 List 对象。可指定排除 NULL 值元素。 public static List ToList(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; } // 安全转换为 T[] 对象。可指定排除 NULL 值元素。 public static T[] ToArray(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]; 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]; Array.Copy(array, 0, collapsed, 0, added); return collapsed; } } public static bool IsEmpty(IEnumerable objects) { if (objects == null) return true; if (objects is T[]) return ((T[])objects).LongLength == 0; if (objects is ICollection) return ((ICollection)objects).Count == 0; foreach (var i in objects) return false; return true; } public static bool NotEmpty(IEnumerable objects) => !IsEmpty(objects); // 判断集合包含特定值。 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; } // 获取集合中元素的数量。 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; } // 对元素去重,且去除 NULL 值。 public static T[] Distinct(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]; Array.Copy(array, 0, temp, 0, added); array = temp; } return array; } // 获取可枚举集合的部分元素。 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 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; } } }