<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Collections.Specialized;
using Signum.Utilities.Properties;
using Signum.Utilities.Reflection;
using Signum.Utilities.ExpressionTrees;

namespace Signum.Utilities
{
    public static class DictionaryExtensions
    {
        public static V TryGet<K, V>(this IDictionary<K, V> dictionary, K key, V defaultValue)
        {
            if (dictionary == null)
                return defaultValue;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return defaultValue;
        }

        public static V TryGetC<K, V>(this IDictionary<K, V> dictionary, K key) where V : class
        {
            if (dictionary == null)
                return null;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V? TryGetS<K, V>(this IDictionary<K, V> dictionary, K key) where V : struct
        {
            if (dictionary == null)
                return null;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V? TryGetS<K, V>(this IDictionary<K, V?> dictionary, K key) where V : struct
        {
            if (dictionary == null)
                return null;

            V? result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key) where V : new()
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = new V();
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key, V value)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = value;
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key, Func<V> generator)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = generator();
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, Func<K, Exception> exception)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw exception(key);
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, string messageWithFormat)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw new KeyNotFoundException(messageWithFormat.Formato(key));
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw new KeyNotFoundException("Key '{0}' ({1}) not found on {2}".Formato(key, key.GetType().TypeName(), dictionary.GetType().TypeName()));
            return result;
        }

        public static void AddOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, V value, string message)
        {
            if (dictionary.ContainsKey(key))
                throw new ArgumentException(message.Formato(key));

            dictionary.Add(key, value);
        }

        public static Dictionary<K2, V2> SelectDictionary<K1, V1, K2, V2>(this IDictionary<K1, V1> dictionary, Func<K1, K2> mapKey, Func<V1, V2> mapValue)
        {
            return dictionary.ToDictionary(p => mapKey(p.Key), p => mapValue(p.Value));
        }

        public static Dictionary<K2, V2> SelectDictionary<K1, V1, K2, V2>(this IDictionary<K1, V1> dictionary, Func<K1, K2> mapKey, Func<K1, V1, V2> mapValue)
        {
            return dictionary.ToDictionary(p => mapKey(p.Key), p => mapValue(p.Key, p.Value));
        }

        public static Dictionary<K, V> ToDictionary<K, V>(this IEnumerable<KeyValuePair<K, V>> collection)
        {
            var result = new Dictionary<K, V>();
            result.AddRange<K, V>(collection);
            return result;
        }

        public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, string errorContext)
        {
            Dictionary<TKey, TSource> result = new Dictionary<TKey, TSource>();
            result.AddRange(source, keySelector, v => v, errorContext);
            return result;
        }

        public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, string errorContext)
        {
            Dictionary<TKey, TElement> result = new Dictionary<TKey, TElement>();
            result.AddRange(source, keySelector, elementSelector, errorContext);
            return result;
        }

        public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, string errorContext)
        {
            Dictionary<TKey, TSource> result = new Dictionary<TKey, TSource>(comparer);
            result.AddRange(source, keySelector, v => v, errorContext);
            return result;
        }

        public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, string errorContext)<commit_msg>errorContext in ToDictionary()<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Collections.Specialized;
using Signum.Utilities.Properties;
using Signum.Utilities.Reflection;
using Signum.Utilities.ExpressionTrees;

namespace Signum.Utilities
{
    public static class DictionaryExtensions
    {
        public static V TryGet<K, V>(this IDictionary<K, V> dictionary, K key, V defaultValue)
        {
            if (dictionary == null)
                return defaultValue;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return defaultValue;
        }

        public static V TryGetC<K, V>(this IDictionary<K, V> dictionary, K key) where V : class
        {
            if (dictionary == null)
                return null;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V? TryGetS<K, V>(this IDictionary<K, V> dictionary, K key) where V : struct
        {
            if (dictionary == null)
                return null;

            V result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V? TryGetS<K, V>(this IDictionary<K, V?> dictionary, K key) where V : struct
        {
            if (dictionary == null)
                return null;

            V? result;
            if (dictionary.TryGetValue(key, out result))
                return result;
            return null;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key) where V : new()
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = new V();
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key, V value)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = value;
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrCreate<K, V>(this IDictionary<K, V> dictionary, K key, Func<V> generator)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
            {
                result = generator();
                dictionary.Add(key, result);
            }
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, Func<K, Exception> exception)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw exception(key);
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, string messageWithFormat)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw new KeyNotFoundException(messageWithFormat.Formato(key));
            return result;
        }

        public static V GetOrThrow<K, V>(this IDictionary<K, V> dictionary, K key)
        {
            V result;
            if (!dictionary.TryGetValue(key, out result))
                throw new KeyNotFoundException("Key '{0}' ({1}) not found on {2}".Formato(key, key.GetType().TypeName(), dictionary.GetType().TypeName()));
            return result;
        }

        public static void AddOrThrow<K, V>(this IDictionary<K, V> dictionary, K key, V value, string message)
        {
            if (dictionary.ContainsKey(key))
                throw new ArgumentException(message.Formato(key));

            dictionary.Add(key, value);
        }

        public static Dictionary<K2, V2> SelectDictionary<K1, V1, K2, V2>(this IDictionary<K1, V1> dictionary, Func<K1, K2> mapKey, Func<V1, V2> mapValue)
        {
            return dictionary.ToDictionary(p => mapKey(p.Key), p => mapValue(p.Value));
        }

        public static Dictionary<K2, V2> SelectDictionary<K1, V1, K2, V2>(this IDictionary<K1, V1> dictionary, Func<K1, K2> mapKey, Func<K1, V1, V2> mapValue)
        {
            return dictionary.ToDictionary(p => mapKey(p.Key), p => mapValue(p.Key, p.Value));
        }

        public static Dictionary<K, V> ToDictionary<K, V>(this IEnumerable<KeyValuePair<K, V>> collection)
        {
            var result = new Dictionary<K, V>();
            result.AddRange<K, V>(collection);
            return result;
        }

        public static Dictionary<K, V> ToDictionary<K, V>(this IEnumerable<KeyValuePair<K, V>> collection, string errorContext)
        {
            var result = new Dictionary<K, V>();
            result.AddRange<K, V>(collection, errorContext);
            return result;
        }

        public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, string errorContext)
        {
            Dictionary<TKey, TSource> result = new Dictionary<TKey, TSource>();
            result.AddRange(source, keySelector, v => v, errorContext);
            return result;
        }

        public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, string errorContext)
        {
            Dictionary<TKey, TElement> result = new Dictionary<TKey, TElement>();
            result.AddRange(source, keySelector, elementSelector, errorContext);
            return result;
        }

        public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, string errorContext)
        {
            Dictionary<TKey, TSource> result = new Dictionary<TKey, TSource>(comparer);
            result.AddRange(source, keySelector, v => v, errorContext);
            return result;
        }

        public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, string errorContext)
{'fraction_non_alphanumeric': 0.10094436949448457, 'fraction_numerical': 0.004444091738750893, 'mean_word_length': 2.1016490278119617, 'pattern_counts': {'":': 0, '<': 141, '<?xml version=': 0, '>': 153, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6188340', 'n_tokens_mistral': 3491, 'n_tokens_neox': 3390, 'n_words': 964}