From e65bc41c067287495aa1d0a9d87b9f590d890e32 Mon Sep 17 00:00:00 2001 From: FoggyFinder Date: Tue, 19 Nov 2019 11:10:16 +0200 Subject: [PATCH 1/5] fix BiDictionary.Remove --- CSharpMath.Tests/Generic/BiDictionaryTests.cs | 31 +++++++++++++++++++ CSharpMath/Generic/BiDictionary.cs | 22 +++++++++---- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 CSharpMath.Tests/Generic/BiDictionaryTests.cs diff --git a/CSharpMath.Tests/Generic/BiDictionaryTests.cs b/CSharpMath.Tests/Generic/BiDictionaryTests.cs new file mode 100644 index 000000000..28ff720f0 --- /dev/null +++ b/CSharpMath.Tests/Generic/BiDictionaryTests.cs @@ -0,0 +1,31 @@ +using Xunit; + +namespace CSharpMath.Tests.Generic { + public class BiDictionaryTests { + [Fact] + public void TestRemove() { + var testBiDictionary = new BiDictionary { + { 0, "0" }, + { 1, "1" }, + { 2, "8" }, + { 3, "10" } + }; + Assert.Equal(4, testBiDictionary.Firsts.Count); + Assert.Equal(4, testBiDictionary.Seconds.Count); + + Assert.True(testBiDictionary.Remove(2, "8")); + Assert.Equal(3, testBiDictionary.Firsts.Count); + Assert.Equal(3, testBiDictionary.Seconds.Count); + + // Remove with wrong second key + Assert.False(testBiDictionary.Remove(3, "15")); + Assert.Equal(3, testBiDictionary.Firsts.Count); + Assert.Equal(3, testBiDictionary.Seconds.Count); + + // Remove when both exists but not corresponding to each other + Assert.True(testBiDictionary.Remove(0, "1")); + Assert.Single(testBiDictionary.Firsts); + Assert.Single(testBiDictionary.Seconds); + } + } +} diff --git a/CSharpMath/Generic/BiDictionary.cs b/CSharpMath/Generic/BiDictionary.cs index 61c671a61..91dff4edb 100644 --- a/CSharpMath/Generic/BiDictionary.cs +++ b/CSharpMath/Generic/BiDictionary.cs @@ -245,12 +245,22 @@ public void CopyTo(KeyValuePair[] array, int arrayIndex) { array[arrayIndex++] = pair; } - public bool Remove(TFirst first, TSecond second) => - firstToSecond.Remove(first) && secondToFirst.Remove(second); - public bool Remove(KeyValuePair pair) => - firstToSecond.Remove(pair.Key) && secondToFirst.Remove(pair.Value); - public bool RemoveFirst(TFirst first) => Remove(first, firstToSecond[first]); - public bool RemoveSecond(TSecond second) => Remove(secondToFirst[second], second); + public bool Remove(TFirst first, TSecond second) { + if (TryGetByFirst(first, out var svalue) && TryGetBySecond(second, out var fvalue)) { + + firstToSecond.Remove(first); + firstToSecond.Remove(fvalue); + + secondToFirst.Remove(second); + secondToFirst.Remove(svalue); + return true; + } + return false; + } + + public bool Remove(KeyValuePair pair) => Remove(pair.Key, pair.Value); + public bool RemoveByFirst(TFirst first) => Remove(first, firstToSecond[first]); + public bool RemoveBySecond(TSecond second) => Remove(secondToFirst[second], second); } public class MultiDictionary : IEnumerable> { From f56bceab51a4e3a642afd27f93c2f643923120e1 Mon Sep 17 00:00:00 2001 From: FoggyFinder Date: Tue, 19 Nov 2019 11:24:47 +0200 Subject: [PATCH 2/5] add one more case --- CSharpMath.Tests/Generic/BiDictionaryTests.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CSharpMath.Tests/Generic/BiDictionaryTests.cs b/CSharpMath.Tests/Generic/BiDictionaryTests.cs index 28ff720f0..34432ae8e 100644 --- a/CSharpMath.Tests/Generic/BiDictionaryTests.cs +++ b/CSharpMath.Tests/Generic/BiDictionaryTests.cs @@ -17,6 +17,11 @@ public void TestRemove() { Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); + // Remove with wrong first key + Assert.False(testBiDictionary.Remove(4, "10")); + Assert.Equal(3, testBiDictionary.Firsts.Count); + Assert.Equal(3, testBiDictionary.Seconds.Count); + // Remove with wrong second key Assert.False(testBiDictionary.Remove(3, "15")); Assert.Equal(3, testBiDictionary.Firsts.Count); From ccc1224a632e61bf11ea8613899240531ad1aacf Mon Sep 17 00:00:00 2001 From: FoggyFinder Date: Thu, 21 Nov 2019 10:35:21 +0200 Subject: [PATCH 3/5] one more check --- CSharpMath.Tests/Generic/BiDictionaryTests.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CSharpMath.Tests/Generic/BiDictionaryTests.cs b/CSharpMath.Tests/Generic/BiDictionaryTests.cs index 34432ae8e..54c9e6e5c 100644 --- a/CSharpMath.Tests/Generic/BiDictionaryTests.cs +++ b/CSharpMath.Tests/Generic/BiDictionaryTests.cs @@ -14,21 +14,29 @@ public void TestRemove() { Assert.Equal(4, testBiDictionary.Seconds.Count); Assert.True(testBiDictionary.Remove(2, "8")); + Assert.False(testBiDictionary.Contains(2)); + Assert.False(testBiDictionary.Contains("8")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove with wrong first key Assert.False(testBiDictionary.Remove(4, "10")); + Assert.False(testBiDictionary.Contains(4)); + Assert.True(testBiDictionary.Contains("10")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove with wrong second key Assert.False(testBiDictionary.Remove(3, "15")); + Assert.True(testBiDictionary.Contains(3)); + Assert.False(testBiDictionary.Contains("15")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove when both exists but not corresponding to each other Assert.True(testBiDictionary.Remove(0, "1")); + Assert.False(testBiDictionary.Contains(0)); + Assert.False(testBiDictionary.Contains("1")); Assert.Single(testBiDictionary.Firsts); Assert.Single(testBiDictionary.Seconds); } From cc726f4aed7e6dc1b0d69f628f55a8ff386a316a Mon Sep 17 00:00:00 2001 From: FoggyFinder Date: Thu, 21 Nov 2019 10:58:03 +0200 Subject: [PATCH 4/5] rename Contains methods to avoid ambiguity when TFirst and TSecond has the same type. --- CSharpMath.Tests/Generic/BiDictionaryTests.cs | 16 ++++++++-------- CSharpMath/Generic/BiDictionary.cs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CSharpMath.Tests/Generic/BiDictionaryTests.cs b/CSharpMath.Tests/Generic/BiDictionaryTests.cs index 54c9e6e5c..d1173410a 100644 --- a/CSharpMath.Tests/Generic/BiDictionaryTests.cs +++ b/CSharpMath.Tests/Generic/BiDictionaryTests.cs @@ -14,29 +14,29 @@ public void TestRemove() { Assert.Equal(4, testBiDictionary.Seconds.Count); Assert.True(testBiDictionary.Remove(2, "8")); - Assert.False(testBiDictionary.Contains(2)); - Assert.False(testBiDictionary.Contains("8")); + Assert.False(testBiDictionary.ContainsByFirst(2)); + Assert.False(testBiDictionary.ContainsBySecond("8")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove with wrong first key Assert.False(testBiDictionary.Remove(4, "10")); - Assert.False(testBiDictionary.Contains(4)); - Assert.True(testBiDictionary.Contains("10")); + Assert.False(testBiDictionary.ContainsByFirst(4)); + Assert.True(testBiDictionary.ContainsBySecond("10")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove with wrong second key Assert.False(testBiDictionary.Remove(3, "15")); - Assert.True(testBiDictionary.Contains(3)); - Assert.False(testBiDictionary.Contains("15")); + Assert.True(testBiDictionary.ContainsByFirst(3)); + Assert.False(testBiDictionary.ContainsBySecond("15")); Assert.Equal(3, testBiDictionary.Firsts.Count); Assert.Equal(3, testBiDictionary.Seconds.Count); // Remove when both exists but not corresponding to each other Assert.True(testBiDictionary.Remove(0, "1")); - Assert.False(testBiDictionary.Contains(0)); - Assert.False(testBiDictionary.Contains("1")); + Assert.False(testBiDictionary.ContainsByFirst(0)); + Assert.False(testBiDictionary.ContainsBySecond("1")); Assert.Single(testBiDictionary.Firsts); Assert.Single(testBiDictionary.Seconds); } diff --git a/CSharpMath/Generic/BiDictionary.cs b/CSharpMath/Generic/BiDictionary.cs index 91dff4edb..1811d96be 100644 --- a/CSharpMath/Generic/BiDictionary.cs +++ b/CSharpMath/Generic/BiDictionary.cs @@ -235,8 +235,8 @@ public void Clear() { secondToFirst.Clear(); } - public bool Contains(TFirst first) => firstToSecond.ContainsKey(first); - public bool Contains(TSecond second) => secondToFirst.ContainsKey(second); + public bool ContainsByFirst(TFirst first) => firstToSecond.ContainsKey(first); + public bool ContainsBySecond(TSecond second) => secondToFirst.ContainsKey(second); public bool Contains(KeyValuePair pair) => firstToSecond.TryGetValue(pair.Key, out var second) && EqualityComparer.Default.Equals(second, pair.Value); From 31dfcbeec59405ccf54ff983d5c534f6ee55a5fc Mon Sep 17 00:00:00 2001 From: FoggyFinder Date: Thu, 21 Nov 2019 11:42:48 +0200 Subject: [PATCH 5/5] AddOrReplace method --- CSharpMath.Tests/Generic/BiDictionaryTests.cs | 29 +++++++++++++++++++ CSharpMath/Generic/BiDictionary.cs | 11 ++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CSharpMath.Tests/Generic/BiDictionaryTests.cs b/CSharpMath.Tests/Generic/BiDictionaryTests.cs index d1173410a..8ab71efb5 100644 --- a/CSharpMath.Tests/Generic/BiDictionaryTests.cs +++ b/CSharpMath.Tests/Generic/BiDictionaryTests.cs @@ -40,5 +40,34 @@ public void TestRemove() { Assert.Single(testBiDictionary.Firsts); Assert.Single(testBiDictionary.Seconds); } + + [Fact] + public void TestAddOrReplace() { + var testBiDictionary = new BiDictionary(); + + testBiDictionary.AddOrReplace(0, "Value1"); + Assert.Equal("Value1", testBiDictionary[0]); + Assert.Equal(0, testBiDictionary["Value1"]); + + testBiDictionary.AddOrReplace(2, "Value10"); + Assert.Equal("Value10", testBiDictionary[2]); + Assert.Equal(2, testBiDictionary["Value10"]); + + testBiDictionary.AddOrReplace(2, "Value2"); + Assert.Equal("Value2", testBiDictionary[2]); + Assert.Equal(2, testBiDictionary["Value2"]); + Assert.Equal(2, testBiDictionary.Firsts.Count); + Assert.Equal(2, testBiDictionary.Seconds.Count); + + testBiDictionary.AddOrReplace(3, "Value3"); + Assert.Equal("Value3", testBiDictionary[3]); + Assert.Equal(3, testBiDictionary["Value3"]); + + testBiDictionary.AddOrReplace(10, "Value3"); + Assert.Equal("Value3", testBiDictionary[10]); + Assert.Equal(10, testBiDictionary["Value3"]); + Assert.Equal(3, testBiDictionary.Firsts.Count); + Assert.Equal(3, testBiDictionary.Seconds.Count); + } } } diff --git a/CSharpMath/Generic/BiDictionary.cs b/CSharpMath/Generic/BiDictionary.cs index 1811d96be..39f3fc05a 100644 --- a/CSharpMath/Generic/BiDictionary.cs +++ b/CSharpMath/Generic/BiDictionary.cs @@ -203,6 +203,15 @@ public void Add(TFirst first, TSecond second) { secondToFirst.Add(second, first); } + public void AddOrReplace(TFirst first, TSecond second) { + if (firstToSecond.ContainsKey(first)) + RemoveByFirst(first); + if (secondToFirst.ContainsKey(second)) + RemoveBySecond(second); + firstToSecond.Add(first, second); + secondToFirst.Add(second, first); + } + public Dictionary.KeyCollection Firsts => firstToSecond.Keys; public Dictionary.KeyCollection Seconds => secondToFirst.Keys; @@ -229,7 +238,7 @@ IEnumerator> IEnumerable item) => Add(item.Key, item.Value); - + public void AddOrReplace(KeyValuePair item) => AddOrReplace(item.Key, item.Value); public void Clear() { firstToSecond.Clear(); secondToFirst.Clear();