/* * Copyright (C) 2012-2017 CypherCore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System.Linq; namespace System.Collections.Generic { public static class CollectionExtensions { public static bool Empty(this ICollection collection) { return collection.Count == 0; } public static bool Empty(this IDictionary dictionary) { return dictionary.Count == 0; } /// /// Returns the entry in this list at the given index, or the default value of the element /// type if the index was out of bounds. /// /// The type of the elements in the list. /// The list to retrieve from. /// The index to try to retrieve at. /// The value, or the default value of the element type. public static T LookupByIndex(this IList list, int index) { return index >= list.Count ? default(T) : list[index]; } /// /// Returns the entry in this dictionary at the given key, or the default value of the key /// if none. /// /// The key type. /// The value type. /// The dictionary to operate on. /// The key of the element to retrieve. /// The value (if any). public static TValue LookupByKey(this IDictionary dict, object key) { TValue val; TKey newkey = (TKey)Convert.ChangeType(key, typeof(TKey)); return dict.TryGetValue(newkey, out val) ? val : default(TValue); } public static TValue LookupByKey(this IDictionary dict, TKey key) { TValue val; return dict.TryGetValue(key, out val) ? val : default(TValue); } public static KeyValuePair Find(this IDictionary dict, TKey key) { return new KeyValuePair(key, dict[key]); } public static bool ContainsKey(this IDictionary dict, object key) { TKey newkey = (TKey)Convert.ChangeType(key, typeof(TKey)); return dict.ContainsKey(newkey); } public static void RemoveAll(this List collection, ICheck check) { collection.RemoveAll(check.Invoke); } public static IEnumerable Shuffle(this IEnumerable source) { return source.OrderBy(x => Guid.NewGuid()); } public static void Swap(this T[] array, int position1, int position2) { // // Swaps elements in an array. Doesn't need to return a reference. // T temp = array[position1]; // Copy the first position's element array[position1] = array[position2]; // Assign to the second element array[position2] = temp; // Assign to the first element } public static void Resize(this List list, uint size) { int cur = list.Count; if (size < cur) list.RemoveRange((int)size, cur - (int)size); } public static void RandomResize(this IList list, uint size) { int listSize = list.Count; while (listSize > size) { list.RemoveAt(RandomHelper.IRand(0, listSize)); --listSize; } } public static void RandomResize(this ICollection list, Predicate predicate, uint size) { List listCopy = new List(); foreach (var obj in list) if (predicate(obj)) listCopy.Add(obj); if (size != 0) listCopy.Resize(size); list = listCopy; } public static T SelectRandom(this IEnumerable source) { return source.SelectRandom(1).Single(); } public static IEnumerable SelectRandom(this IEnumerable source, uint count) { return source.Shuffle().Take((int)count); } public static T SelectRandomElementByWeight(this IEnumerable sequence, Func weightSelector) { float totalWeight = sequence.Sum(weightSelector); // The weight we are after... float itemWeightIndex = (float)RandomHelper.NextDouble() * totalWeight; float currentWeightIndex = 0; foreach (var item in from weightedItem in sequence select new { Value = weightedItem, Weight = weightSelector(weightedItem) }) { currentWeightIndex += item.Weight; // If we've hit or passed the weight we are after for this item then it's the one we want.... if (currentWeightIndex >= itemWeightIndex) return item.Value; } return default(T); } public static uint[] ToBlockRange(this BitSet array) { uint[] blockValues = new uint[array.Length / 32 + 1]; array.CopyTo(blockValues, 0); return blockValues; } } public interface ICheck { bool Invoke(T obj); } public interface IDoWork { void Invoke(T obj); } }