using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
using System.Runtime.Serialization;
namespace Sleis.Utility
{
///
/// Basic helper functions for dealing with collections.
///
public static class CollectionUtility
{
public static Dictionary CreateDictionaryFromPairs(params T[] pairs)
{
if (MathUtility.IsOdd(pairs.Length))
{
throw new ArgumentException("pairs.Length is odd");
}
Dictionary dictionary = new Dictionary();
for (int i = 0; i < pairs.Length; i += 2)
{
dictionary.Add(pairs[i], pairs[i + 1]);
}
return dictionary;
}
public static bool IsNullOrEmpty(IEnumerable inArray)
{
if (inArray == null)
{
return true;
}
ICollection collection = inArray as ICollection;
if (collection != null)
{
return (collection.Count == 0);
}
else
{
foreach (object item in inArray)
{
return false;
}
return true;
}
}
public static bool MoreThanOne(IEnumerable inArray)
{
if (inArray == null)
{
return false;
}
ICollection collection = inArray as ICollection;
if (collection != null)
{
return (collection.Count > 1);
}
else
{
int count = 0;
foreach (object item in inArray)
{
if (++count > 1)
{
return true;
}
}
return false;
}
}
public static bool IndexInRange(IEnumerable inArray, int inIndex)
{
return (inIndex > -1) && (inIndex < Count(inArray));
}
public static int Count(IEnumerable inArray)
{
if (inArray == null)
{
return 0;
}
ICollection collection = inArray as ICollection;
if (collection != null)
{
return collection.Count;
}
else
{
int count = 0;
foreach (object item in inArray)
{
++count;
}
return count;
}
}
public static T[] ToArray(IEnumerable inArray)
{
if (inArray != null)
{
ICollection collection = inArray as ICollection;
if (collection != null)
{
T[] rtnArray = new T[collection.Count];
int i = 0;
foreach (T item in inArray)
{
rtnArray[i++] = item;
}
return rtnArray;
}
else
{
List rtnArray = new List();
foreach (T item in inArray)
{
rtnArray.Add(item);
}
return rtnArray.ToArray();
}
}
else
{
return new T[0];
}
}
public static List ToList(IEnumerable inArray)
{
if (inArray != null)
{
List rtnList;
ICollection collection = inArray as ICollection;
if (collection != null)
{
rtnList = new List(collection.Count);
}
else
{
rtnList = new List();
}
foreach (object item in inArray)
{
rtnList.Add((T)item);
}
return rtnList;
}
else
{
return new List();
}
}
public static List ToList(IEnumerable inArray) where T : K
{
if (inArray != null)
{
List rtnList;
ICollection collection = inArray as ICollection;
if (collection != null)
{
rtnList = new List(collection.Count);
}
else
{
rtnList = new List();
}
foreach (K item in inArray)
{
rtnList.Add((T)item);
}
return rtnList;
}
else
{
return new List();
}
}
public static T[] ToArray(IEnumerable inArray) where T : K
{
if (inArray != null)
{
List rtnList;
ICollection collection = inArray as ICollection;
if (collection != null)
{
rtnList = new List(collection.Count);
}
else
{
rtnList = new List();
}
foreach (K item in inArray)
{
rtnList.Add((T)item);
}
return rtnList.ToArray();
}
else
{
return new T[0];
}
}
public static void InsertIntoSortedListAllowDuplicates(List inList, T inElement)
{
int index = inList.BinarySearch(inElement);
if (index < 0)
{
index = ~index;
}
inList.Insert(index, inElement);
}
public static void InsertIntoSortedListAllowDuplicates(List inList, T inElement, IComparer comparer)
{
int index = inList.BinarySearch(inElement, comparer);
if (index < 0)
{
index = ~index;
}
inList.Insert(index, inElement);
}
public static bool InsertIntoSortedList(List inList, T inElement)
{
int index = inList.BinarySearch(inElement);
if (index < 0)
{
inList.Insert(~index, inElement);
return true;
}
return false;
}
public static bool InsertIntoSortedList(List inList, T inElement, IComparer comparer)
{
int index = inList.BinarySearch(inElement, comparer);
if (index < 0)
{
inList.Insert(~index, inElement);
return true;
}
return false;
}
///
/// Perform a binary search on the input list attempting to locate an object represented by
/// inCompareParam. Return values are the same as List.BinarySearch().
///
public static bool SortedListContains(List inList, T inValue)
{
return (inList.BinarySearch(inValue) >= 0);
}
public static bool SortedListContains(List inList, T inValue, IComparer comparer)
{
return (inList.BinarySearch(inValue, comparer) >= 0);
}
public static T FirstItem(IEnumerable inArray)
{
return NthItem(inArray, 0);
}
public static object FirstItem(IEnumerable inArray)
{
return NthItem(inArray, 0);
}
public static T NthItem(IEnumerable inArray, int index)
{
if (index < 0)
{
throw new IndexOutOfRangeException(string.Format("index \"{0}\" is negative",
index.ToString()));
}
using (IEnumerator enumerator = inArray.GetEnumerator())
{
int curIndex = 0;
while (enumerator.MoveNext())
{
if (curIndex++ == index)
{
return enumerator.Current;
}
}
throw new IndexOutOfRangeException(string.Format("index \"{0}\" is out of range for the array length \"{1}\"",
index.ToString(), curIndex.ToString()));
}
}
public static object NthItem(IEnumerable inArray, int index)
{
if (index < 0)
{
throw new IndexOutOfRangeException(string.Format("index \"{0}\" is negative",
index.ToString()));
}
IEnumerator enumerator = inArray.GetEnumerator();
int curIndex = 0;
while (enumerator.MoveNext())
{
if (curIndex++ == index)
{
return enumerator.Current;
}
}
throw new IndexOutOfRangeException(string.Format("index \"{0}\" is out of range for the array length \"{1}\"",
index.ToString(), curIndex.ToString()));
}
public static bool KeysMatch(IDictionary dictA, IDictionary dictB)
{
if (IsNullOrEmpty(dictA) && IsNullOrEmpty(dictB))
{
return true;
}
if ((dictA == null) || (dictB == null) || (dictA.Count != dictB.Count))
{
return false;
}
foreach (KeyValuePair pair in dictA)
{
if (!dictB.ContainsKey(pair.Key))
{
return false;
}
}
return true;
}
public static T[] RemoveNullElements(T[] inArray) where T : class
{
if (inArray == null)
{
return null;
}
bool hasNulls = false;
foreach (T element in inArray)
{
if (element == null)
{
hasNulls = true;
break;
}
}
if (hasNulls)
{
List rtnList = new List(inArray.Length);
foreach (T element in inArray)
{
if (element != null)
{
rtnList.Add(element);
}
}
return rtnList.ToArray();
}
else
{
return inArray;
}
}
public static Type GetCollectionElementType(ICollection collection)
{
return GetCollectionElementType(collection.GetType());
}
///
/// If the input type implements ICollection, return the type of elements that are stored
/// in the collection; otherwise, return null.
///
public static Type GetCollectionElementType(Type collectionType)
{
if (typeof(ICollection).IsAssignableFrom(collectionType))
{
if (collectionType.IsArray)
{
if (collectionType.HasElementType)
{
return collectionType.GetElementType();
}
}
else if (collectionType.IsGenericType)
{
Type[] args = collectionType.GetGenericArguments();
if ((args.Length == 1) &&
typeof(ICollection<>).MakeGenericType(args).IsAssignableFrom(collectionType))
{
return args[0];
}
}
}
return null;
}
public static List CreateStringList(StringCollection collection)
{
List list = new List();
if (!CollectionUtility.IsNullOrEmpty(collection))
{
list.Capacity = collection.Count;
foreach (string value in collection)
{
list.Add(value);
}
}
return list;
}
public static StringCollection CreateStringCollection(IEnumerable list)
{
StringCollection collection = new StringCollection();
if (list != null)
{
foreach (string value in list)
{
collection.Add(value);
}
}
return collection;
}
public static void Add(T obj, ref List list)
{
if (list == null)
{
list = new List();
}
list.Add(obj);
}
public static void Add(K key, V value, ref Dictionary dictionary)
{
if (dictionary == null)
{
dictionary = new Dictionary();
}
dictionary.Add(key, value);
}
///
/// Create and return a collection of the type specified by collectionType, and copy any elements from elementsToCopy
/// to the new array.
///
public static ICollection CreateCollectionFromCollection(Type collectionType, ICollection elementsToCopy)
{
Type memberElementType = CollectionUtility.GetCollectionElementType(collectionType);
if (memberElementType == null)
{
throw new ArgumentException(string.Format("The input collection type, \"{0},\" does not implement ICollection or the type of collection elements cannot be determined",
collectionType.FullName));
}
int collectionSize = 0;
if (elementsToCopy != null)
{
// Value and member types are ICollections, do collection conversion here:
Type elementsToCopyElementType = CollectionUtility.GetCollectionElementType(elementsToCopy);
if (elementsToCopyElementType == null)
{
throw new ArgumentException(string.Format("The type of collection elements for elementsToCopy, \"{0},\" cannot be determined",
elementsToCopy.GetType().FullName));
}
if (elementsToCopyElementType != memberElementType)
{
throw new ArgumentException(string.Format("ICollection element types do not match: \"{0}\" vs. \"{1}\"",
elementsToCopyElementType.ToString(), memberElementType.ToString()));
}
collectionSize = elementsToCopy.Count;
}
if (collectionType.IsArray)
{
Array newArray = Array.CreateInstance(memberElementType, collectionSize);
if (collectionSize > 0)
{
elementsToCopy.CopyTo(newArray, 0);
}
return newArray;
}
else
{
if (typeof(IList).IsAssignableFrom(collectionType))
{
IList newCollection = (IList)Activator.CreateInstance(collectionType, collectionSize);
if (collectionSize > 0)
{
foreach (object element in elementsToCopy)
{
newCollection.Add(element);
}
}
return newCollection;
}
else
{
throw new NotSupportedException(string.Format("The ICollection type \"{0}\" is not supported yet",
collectionType.FullName));
}
}
}
public static bool HaveSameLengths(params ICollection[] collections)
{
if (CollectionUtility.IsNullOrEmpty(collections))
{
return true;
}
int length = -1;
foreach (ICollection collection in collections)
{
if (collection == null)
{
if (length == -1)
{
length = 0;
}
else if (length != 0)
{
return false;
}
}
else
{
if (length == -1)
{
length = collection.Count;
}
else if (length != collection.Count)
{
return false;
}
}
}
return true;
}
public delegate void ForEachDelegate(T obj);
public delegate bool ForEachBreakDelegate(T obj);
public static void ForEachBreak(IEnumerable list, ForEachBreakDelegate forEachProc)
{
if (!CollectionUtility.IsNullOrEmpty(list))
{
foreach (T obj in list)
{
if (!forEachProc(obj))
{
break;
}
}
}
}
public static void ForEach(IEnumerable list, ForEachDelegate forEachProc)
{
if (!CollectionUtility.IsNullOrEmpty(list))
{
foreach (T obj in list)
{
forEachProc(obj);
}
}
}
public static void ForEach(IEnumerable list, ForEachDelegate