diff --git a/SabreTools.Collections.Extensions.Test/DictionaryExtensionsTests.cs b/SabreTools.Collections.Extensions.Test/DictionaryExtensionsTests.cs index 20edec1..0cf0fa9 100644 --- a/SabreTools.Collections.Extensions.Test/DictionaryExtensionsTests.cs +++ b/SabreTools.Collections.Extensions.Test/DictionaryExtensionsTests.cs @@ -5,10 +5,10 @@ namespace SabreTools.Collections.Extensions.Test { public class DictionaryExtensionsTests { - #region MergeWith + #region MergeWith (String) [Fact] - public void MergeWith_EmptySource_EmptyOther_Empty() + public void MergeWithString_EmptySource_EmptyOther_Empty() { Dictionary> source = []; Dictionary> other = []; @@ -18,7 +18,7 @@ namespace SabreTools.Collections.Extensions.Test } [Fact] - public void MergeWith_EmptySource_EmptyKeyOther_Empty() + public void MergeWithString_EmptySource_EmptyKeyOther_Empty() { Dictionary> source = []; Dictionary> other = []; @@ -29,7 +29,7 @@ namespace SabreTools.Collections.Extensions.Test } [Fact] - public void MergeWith_EmptySource_FilledOther_Filled() + public void MergeWithString_EmptySource_FilledOther_Filled() { Dictionary> source = []; Dictionary> other = []; @@ -44,7 +44,7 @@ namespace SabreTools.Collections.Extensions.Test } [Fact] - public void MergeWith_FilledSource_EmptyOther_Filled() + public void MergeWithString_FilledSource_EmptyOther_Filled() { Dictionary> source = []; source.Add("key", ["value"]); @@ -59,7 +59,7 @@ namespace SabreTools.Collections.Extensions.Test } [Fact] - public void MergeWith_FilledSource_FilledOther_Filled() + public void MergeWithString_FilledSource_FilledOther_Filled() { Dictionary> source = []; source.Add("key1", ["value1"]); @@ -81,5 +81,83 @@ namespace SabreTools.Collections.Extensions.Test } #endregion + + #region MergeWith (Generic) + + [Fact] + public void MergeWithGeneric_EmptySource_EmptyOther_Empty() + { + Dictionary> source = []; + Dictionary> other = []; + + source.MergeWith(other); + Assert.Empty(source); + } + + [Fact] + public void MergeWithGeneric_EmptySource_EmptyKeyOther_Empty() + { + Dictionary> source = []; + Dictionary> other = []; + other.Add("key", []); + + source.MergeWith(other); + Assert.Empty(source); + } + + [Fact] + public void MergeWithGeneric_EmptySource_FilledOther_Filled() + { + Dictionary> source = []; + Dictionary> other = []; + other.Add("key", [1]); + + source.MergeWith(other); + string key = Assert.Single(source.Keys); + Assert.Equal("key", key); + List actual = source[key]; + int value = Assert.Single(actual); + Assert.Equal(1, value); + } + + [Fact] + public void MergeWithGeneric_FilledSource_EmptyOther_Filled() + { + Dictionary> source = []; + source.Add("key", [1]); + Dictionary> other = []; + + source.MergeWith(other); + string key = Assert.Single(source.Keys); + Assert.Equal("key", key); + List actual = source[key]; + int value = Assert.Single(actual); + Assert.Equal(1, value); + } + + [Fact] + public void MergeWithGeneric_FilledSource_FilledOther_Filled() + { + Dictionary> source = []; + source.Add("key1", [1]); + Dictionary> other = []; + other.Add("key2", [2]); + + source.MergeWith(other); + Assert.Equal(2, source.Keys.Count); + + Assert.Contains("key1", source.Keys); + List actualKey1 = source["key1"]; + int value1 = Assert.Single(actualKey1); + Assert.Equal(1, value1); + + Assert.Contains("key2", source.Keys); + List actualKey2 = source["key2"]; + int value2 = Assert.Single(actualKey2); + Assert.Equal(2, value2); + } + + #endregion + } } diff --git a/SabreTools.Collections.Extensions/DictionaryExtensions.cs b/SabreTools.Collections.Extensions/DictionaryExtensions.cs index 3f583e8..839ac37 100644 --- a/SabreTools.Collections.Extensions/DictionaryExtensions.cs +++ b/SabreTools.Collections.Extensions/DictionaryExtensions.cs @@ -29,5 +29,32 @@ namespace SabreTools.Collections.Extensions dict[kvp.Key].AddRange(kvp.Value); } } + + /// + /// Merge a dictionary into an existing one, if possible + /// + /// Source dictionary to add to + /// Second dictionary to add from + /// This only performs a shallow copy + public static void MergeWith(this Dictionary> dict, Dictionary> other) + where TKey : notnull + { + // Ignore if there are no values to append + if (other.Count == 0) + return; + + // Loop through and add from the new dictionary + foreach (var kvp in other) + { + // Ignore empty values + if (kvp.Value.Count == 0) + continue; + + if (!dict.ContainsKey(kvp.Key)) + dict[kvp.Key] = []; + + dict[kvp.Key].AddRange(kvp.Value); + } + } } }