/// <summary>
        /// Because the input <see cref="IDictionary{TKey, TValue}"/> is not an <see cref="IDistinctValuedDictionary{TKey, TValue}"/>, duplicate value handling must be specified.
        /// </summary>
        public static Dictionary <TValue, TKey> Invert <TKey, TValue>(this IDictionary <TKey, TValue> dictionary,
                                                                      DuplicateValueHandling duplicateValueHandling = DuplicateValueHandling.Error)
        {
            var output = new Dictionary <TValue, TKey>();

            foreach (var pair in dictionary)
            {
                var key   = pair.Value;
                var value = pair.Key;

                if (output.ContainsKey(key))
                {
                    var existing = output[key];
                    var chosen   = duplicateValueHandling.Choose(existing, value);

                    output[key] = chosen;
                }
                else
                {
                    output.Add(key, value);
                }
            }

            return(output);
        }
Example #2
0
        public static TValue Choose <TValue>(this DuplicateValueHandling duplicateValueHandling,
                                             TValue existing,
                                             TValue duplicate)
        {
            if (duplicateValueHandling.ChooseWouldFail(existing, duplicate, out TValue chosen))
            {
                throw new DuplicateValueException <TValue>(existing, duplicate);
            }

            return(chosen);
        }
Example #3
0
        /// <summary>
        /// Note: assumes that <paramref name="existing"/> and <paramref name="duplicate"/> have already been determined to be duplicates.
        /// This method is meant for use in an if()-block, and informs as to whether choosing a duplicate would succeed, or if an exception would be thrown based on the <see cref="DuplicateValueHandling"/> value.
        /// In case of false, the output <paramref name="chosen"/> value is the default value of <typeparamref name="TValue"/>.
        /// In case of true, the chosen value is either the existing (<see cref="DuplicateValueHandling.KeepFirst"/>) or duplicate (<see cref="DuplicateValueHandling.UseLast"/>) value depending on the value of <paramref name="duplicateValueHandling"/>.
        /// </summary>
        public static bool ChooseWouldFail <TValue>(this DuplicateValueHandling duplicateValueHandling,
                                                    TValue existing,
                                                    TValue duplicate,
                                                    out TValue chosen)
        {
            if (duplicateValueHandling == DuplicateValueHandling.Error)
            {
                chosen = default;

                return(true);
            }

            if (duplicateValueHandling == DuplicateValueHandling.KeepFirst)
            {
                chosen = existing;
            }
            else // Use last.
            {
                chosen = duplicate;
            }

            return(false);
        }