using System; using System.Collections.Generic; using System.Linq; using ICD.Common.Properties; namespace ICD.Common.Utils.Extensions { public static class DictionaryExtensions { /// /// Removes the first key with a value matching the given value. /// /// /// /// /// /// False if value is not found in the dictionary. [PublicAPI] public static bool RemoveValue(this IDictionary extends, TValue value) { if (extends == null) throw new ArgumentNullException("extends"); try { TKey key = extends.GetKey(value); return extends.Remove(key); } catch (ArgumentOutOfRangeException) { return false; } } /// /// Removes all keys with the given value. /// /// /// /// /// [PublicAPI] public static void RemoveAllValues(this IDictionary extends, TValue value) { if (extends == null) throw new ArgumentNullException("extends"); foreach (TKey key in extends.GetKeys(value).ToArray()) extends.Remove(key); } /// /// If the key is present in the dictionary return the value, otherwise returns default value. /// /// /// /// /// /// [PublicAPI] public static TValue GetDefault(this IDictionary extends, TKey key) { if (extends == null) throw new ArgumentNullException("extends"); // ReSharper disable once CompareNonConstrainedGenericWithNull if (key == null) throw new ArgumentNullException("key"); return extends.GetDefault(key, default(TValue)); } /// /// If the key is present in the dictionary return the value, otherwise return the default value. /// /// /// /// /// /// /// [PublicAPI] public static TValue GetDefault(this IDictionary extends, TKey key, TValue defaultValue) { if (extends == null) throw new ArgumentNullException("extends"); // ReSharper disable once CompareNonConstrainedGenericWithNull if (key == null) throw new ArgumentNullException("key"); return extends.ContainsKey(key) ? extends[key] : defaultValue; } /// /// If the key is present in the dictionary return the value, otherwise add the default value to the dictionary and return it. /// /// /// /// /// /// /// [PublicAPI] public static TValue GetOrAddDefault(this IDictionary extends, TKey key, TValue defaultValue) { if (extends == null) throw new ArgumentNullException("extends"); // ReSharper disable once CompareNonConstrainedGenericWithNull if (key == null) throw new ArgumentNullException("key"); extends[key] = extends.GetDefault(key, defaultValue); return extends[key]; } /// /// Gets a key for the given value. /// /// /// /// /// /// /// The value does not exist in the dictionary. [PublicAPI] public static TKey GetKey(this IDictionary extends, TValue value) { if (extends == null) throw new ArgumentNullException("extends"); try { return extends.GetKeys(value).First(); } catch (InvalidOperationException) { string message = string.Format("Unable to find Key with Value matching {0}", value); throw new KeyNotFoundException(message); } } /// /// Gets the keys that match the given value. /// /// /// /// /// /// [PublicAPI] public static IEnumerable GetKeys(this IDictionary extends, TValue value) { if (extends == null) throw new ArgumentNullException("extends"); return extends.Where(kvp => EqualityComparer.Default.Equals(kvp.Value, value)) .Select(kvp => kvp.Key); } /// /// Updates the dictionary with items from the other dictionary. /// /// /// /// /// [PublicAPI] public static void Update(this IDictionary extends, IDictionary other) { if (extends == null) throw new ArgumentNullException("extends"); if (other == null) throw new ArgumentNullException("other"); foreach (KeyValuePair pair in other) extends[pair.Key] = pair.Value; } /// /// Adds the sequence of items to the dictionary. /// /// /// /// /// /// [PublicAPI] public static void AddRange(this IDictionary extends, IEnumerable items, Func getKey) { if (extends == null) throw new ArgumentNullException("extends"); if (items == null) throw new ArgumentNullException("items"); if (getKey == null) throw new ArgumentNullException("getKey"); foreach (TValue item in items) extends.Add(getKey(item), item); } /// /// Adds the sequence of items to the dictionary. /// /// /// /// /// /// [PublicAPI] public static void AddRange(this IDictionary extends, IEnumerable items, Func getValue) { if (extends == null) throw new ArgumentNullException("extends"); if (items == null) throw new ArgumentNullException("items"); if (getValue == null) throw new ArgumentNullException("getValue"); foreach (TKey item in items) extends.Add(item, getValue(item)); } /// /// Adds the sequence of items to the dictionary. /// /// /// /// /// [PublicAPI] public static void AddRange(this Dictionary extends, IEnumerable> items) { if (extends == null) throw new ArgumentNullException("extends"); if (items == null) throw new ArgumentNullException("items"); foreach (KeyValuePair item in items) extends.Add(item.Key, item.Value); } /// /// Compares the keys and values of the dictionary to determine equality. /// /// /// /// /// /// [PublicAPI] public static bool DictionaryEqual(this IDictionary extends, IDictionary other) { if (extends == null) throw new ArgumentNullException("extends"); return extends.DictionaryEqual(other, EqualityComparer.Default); } /// /// Compares the keys and values of the dictionary to determine equality. /// /// /// /// /// /// /// [PublicAPI] public static bool DictionaryEqual(this IDictionary extends, IDictionary other, IEqualityComparer valueComparer) { if (extends == null) throw new ArgumentNullException("extends"); if (extends == other) return true; if (other == null) return false; if (extends.Count != other.Count) return false; foreach (KeyValuePair kvp in extends) { TValue secondValue; if (!other.TryGetValue(kvp.Key, out secondValue)) return false; if (!valueComparer.Equals(kvp.Value, secondValue)) return false; } return true; } /// /// Returns the KeyValuePairs in key order. /// /// /// /// /// [PublicAPI] public static IEnumerable> OrderByKey( this IEnumerable> extends) { if (extends == null) throw new ArgumentNullException("extends"); return extends.OrderBy(kvp => kvp.Key); } /// /// Returns a sequence of values ordered by the dictionary keys. /// /// /// /// /// [PublicAPI] public static IEnumerable OrderValuesByKey(this IEnumerable> extends) { if (extends == null) throw new ArgumentNullException("extends"); return extends.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value); } } }