com.wallstop-studios.unity-helpers 1.0.1-rc01 → 1.0.1-rc02
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
namespace UnityHelpers.Core.Extension
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
|
+
using System.Collections.Concurrent;
|
|
4
5
|
using System.Collections.Generic;
|
|
5
6
|
using System.Linq;
|
|
6
7
|
|
|
@@ -8,6 +9,11 @@
|
|
|
8
9
|
{
|
|
9
10
|
public static V GetOrAdd<K, V>(this IDictionary<K, V> dictionary, K key, Func<V> valueProducer)
|
|
10
11
|
{
|
|
12
|
+
if (dictionary is ConcurrentDictionary<K, V> concurrentDictionary)
|
|
13
|
+
{
|
|
14
|
+
return concurrentDictionary.GetOrAdd(key, static (_, existing) => existing(), valueProducer);
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
if (dictionary.TryGetValue(key, out V result))
|
|
12
18
|
{
|
|
13
19
|
return result;
|
|
@@ -15,8 +21,14 @@
|
|
|
15
21
|
|
|
16
22
|
return dictionary[key] = valueProducer();
|
|
17
23
|
}
|
|
24
|
+
|
|
18
25
|
public static V GetOrAdd<K, V>(this IDictionary<K, V> dictionary, K key, Func<K, V> valueProducer)
|
|
19
26
|
{
|
|
27
|
+
if (dictionary is ConcurrentDictionary<K, V> concurrentDictionary)
|
|
28
|
+
{
|
|
29
|
+
return concurrentDictionary.GetOrAdd(key, valueProducer);
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
if (dictionary.TryGetValue(key, out V result))
|
|
21
33
|
{
|
|
22
34
|
return result;
|
|
@@ -25,16 +37,17 @@
|
|
|
25
37
|
return dictionary[key] = valueProducer(key);
|
|
26
38
|
}
|
|
27
39
|
|
|
28
|
-
public static V GetOrElse<K, V>(this
|
|
40
|
+
public static V GetOrElse<K, V>(this IReadOnlyDictionary<K, V> dictionary, K key, Func<V> valueProducer)
|
|
29
41
|
{
|
|
30
42
|
if (dictionary.TryGetValue(key, out V value))
|
|
31
43
|
{
|
|
32
44
|
return value;
|
|
33
45
|
}
|
|
46
|
+
|
|
34
47
|
return valueProducer.Invoke();
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
public static V GetOrElse<K, V>(this
|
|
50
|
+
public static V GetOrElse<K, V>(this IReadOnlyDictionary<K, V> dictionary, K key, Func<K, V> valueProducer)
|
|
38
51
|
{
|
|
39
52
|
if (dictionary.TryGetValue(key, out V value))
|
|
40
53
|
{
|
|
@@ -46,6 +59,11 @@
|
|
|
46
59
|
|
|
47
60
|
public static V GetOrAdd<K, V>(this IDictionary<K, V> dictionary, K key) where V : new()
|
|
48
61
|
{
|
|
62
|
+
if (dictionary is ConcurrentDictionary<K, V> concurrentDictionary)
|
|
63
|
+
{
|
|
64
|
+
return concurrentDictionary.AddOrUpdate(key, _ => new V(), (_, existing) => existing);
|
|
65
|
+
}
|
|
66
|
+
|
|
49
67
|
if (dictionary.TryGetValue(key, out V result))
|
|
50
68
|
{
|
|
51
69
|
return result;
|
|
@@ -54,43 +72,58 @@
|
|
|
54
72
|
return dictionary[key] = new V();
|
|
55
73
|
}
|
|
56
74
|
|
|
57
|
-
public static V GetOrElse<K, V>(this
|
|
75
|
+
public static V GetOrElse<K, V>(this IReadOnlyDictionary<K, V> dictionary, K key, V value)
|
|
58
76
|
{
|
|
59
77
|
return GetOrElse(dictionary, key, () => value);
|
|
60
78
|
}
|
|
61
79
|
|
|
62
|
-
public static
|
|
80
|
+
public static V AddOrUpdate<K, V>(
|
|
81
|
+
this IDictionary<K, V> dictionary, K key, Func<K, V> creator, Func<K, V, V> updater)
|
|
63
82
|
{
|
|
64
|
-
if (dictionary
|
|
83
|
+
if (dictionary is ConcurrentDictionary<K, V> concurrentDictionary)
|
|
65
84
|
{
|
|
66
|
-
return
|
|
85
|
+
return concurrentDictionary.AddOrUpdate(key, creator, updater);
|
|
67
86
|
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
87
|
|
|
71
|
-
public static V AddOrUpdate<K, V>(this IDictionary<K, V> dictionary, K key, Func<K, V> creator, Func<K, V, V> updater)
|
|
72
|
-
{
|
|
73
88
|
V latest = dictionary.TryGetValue(key, out V value) ? updater(key, value) : creator(key);
|
|
74
89
|
dictionary[key] = latest;
|
|
75
90
|
return latest;
|
|
76
91
|
}
|
|
77
92
|
|
|
78
|
-
public static
|
|
93
|
+
public static V TryAdd<K, V>(this IDictionary<K, V> dictionary, K key, Func<K, V> creator)
|
|
94
|
+
{
|
|
95
|
+
if (dictionary is ConcurrentDictionary<K, V> concurrentDictionary)
|
|
96
|
+
{
|
|
97
|
+
return concurrentDictionary.AddOrUpdate(key, creator, (_, existing) => existing);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (dictionary.TryGetValue(key, out V existing))
|
|
101
|
+
{
|
|
102
|
+
return existing;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
V value = creator(key);
|
|
106
|
+
dictionary[key] = value;
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public static Dictionary<K, V> Merge<K, V>(this IReadOnlyDictionary<K, V> lhs, IReadOnlyDictionary<K, V> rhs)
|
|
79
111
|
{
|
|
80
|
-
Dictionary<K, V> result = new
|
|
81
|
-
|
|
112
|
+
Dictionary<K, V> result = new();
|
|
113
|
+
if (0 < lhs.Count)
|
|
82
114
|
{
|
|
83
|
-
|
|
115
|
+
foreach (KeyValuePair<K, V> kvp in lhs)
|
|
84
116
|
{
|
|
85
|
-
|
|
117
|
+
result[kvp.Key] = kvp.Value;
|
|
86
118
|
}
|
|
87
|
-
|
|
88
|
-
result[kvp.Key] = kvp.Value;
|
|
89
119
|
}
|
|
90
120
|
|
|
91
|
-
|
|
121
|
+
if (0 < rhs.Count)
|
|
92
122
|
{
|
|
93
|
-
|
|
123
|
+
foreach (KeyValuePair<K, V> kvp in rhs)
|
|
124
|
+
{
|
|
125
|
+
result[kvp.Key] = kvp.Value;
|
|
126
|
+
}
|
|
94
127
|
}
|
|
95
128
|
|
|
96
129
|
return result;
|
|
@@ -103,38 +136,36 @@
|
|
|
103
136
|
/// <param name="lhs">Basis dictionary.</param>
|
|
104
137
|
/// <param name="rhs">Changed dictionary.</param>
|
|
105
138
|
/// <returns>All elements of rhs that either don't exist in or are different from lhs</returns>
|
|
106
|
-
public static Dictionary<K, V> Difference<K, V>(
|
|
139
|
+
public static Dictionary<K, V> Difference<K, V>(
|
|
140
|
+
this IReadOnlyDictionary<K, V> lhs, IReadOnlyDictionary<K, V> rhs)
|
|
107
141
|
{
|
|
108
|
-
Dictionary<K, V> result = new
|
|
142
|
+
Dictionary<K, V> result = new(rhs.Count);
|
|
109
143
|
foreach (KeyValuePair<K, V> kvp in rhs)
|
|
110
144
|
{
|
|
111
145
|
K key = kvp.Key;
|
|
112
|
-
V existing
|
|
113
|
-
if (lhs.TryGetValue(key, out existing))
|
|
146
|
+
if (lhs.TryGetValue(key, out V existing) && Equals(existing, kvp.Value))
|
|
114
147
|
{
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
result[key] = kvp.Value;
|
|
148
|
+
continue;
|
|
121
149
|
}
|
|
150
|
+
|
|
151
|
+
result[key] = kvp.Value;
|
|
122
152
|
}
|
|
123
153
|
|
|
124
154
|
return result;
|
|
125
155
|
}
|
|
126
156
|
|
|
127
|
-
public static Dictionary<V, K> Reverse<K, V>(this
|
|
157
|
+
public static Dictionary<V, K> Reverse<K, V>(this IReadOnlyDictionary<K, V> dictionary)
|
|
128
158
|
{
|
|
129
|
-
Dictionary<V, K> output = new
|
|
159
|
+
Dictionary<V, K> output = new(dictionary.Count);
|
|
130
160
|
foreach (KeyValuePair<K, V> entry in dictionary)
|
|
131
161
|
{
|
|
132
162
|
output[entry.Value] = entry.Key;
|
|
133
163
|
}
|
|
164
|
+
|
|
134
165
|
return output;
|
|
135
166
|
}
|
|
136
167
|
|
|
137
|
-
public static Dictionary<K, V> ToDictionary<K, V>(this
|
|
168
|
+
public static Dictionary<K, V> ToDictionary<K, V>(this IReadOnlyDictionary<K, V> dictionary)
|
|
138
169
|
{
|
|
139
170
|
return new Dictionary<K, V>(dictionary);
|
|
140
171
|
}
|
|
@@ -144,7 +175,13 @@
|
|
|
144
175
|
return prettyMuchADictionary.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
145
176
|
}
|
|
146
177
|
|
|
147
|
-
public static
|
|
178
|
+
public static Dictionary<K, V> ToDictionary<K, V>(this IEnumerable<(K, V)> prettyMuchADictionary)
|
|
179
|
+
{
|
|
180
|
+
return prettyMuchADictionary.ToDictionary(kvp => kvp.Item1, kvp => kvp.Item2);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static bool ContentEquals<K, V>(
|
|
184
|
+
this IReadOnlyDictionary<K, V> dictionary, IReadOnlyDictionary<K, V> other)
|
|
148
185
|
{
|
|
149
186
|
if (ReferenceEquals(dictionary, other))
|
|
150
187
|
{
|
|
@@ -170,4 +207,4 @@
|
|
|
170
207
|
value = kvp.Value;
|
|
171
208
|
}
|
|
172
209
|
}
|
|
173
|
-
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
namespace UnityHelpers.Tests.Extensions
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using Core.Extension;
|
|
7
|
+
using NUnit.Framework;
|
|
8
|
+
|
|
9
|
+
public sealed class DictionaryExtensionTests
|
|
10
|
+
{
|
|
11
|
+
[Test]
|
|
12
|
+
public void GetOrAddValueProducer()
|
|
13
|
+
{
|
|
14
|
+
Dictionary<string, int> dictionary = new();
|
|
15
|
+
int value = dictionary.GetOrAdd("test", () => 100);
|
|
16
|
+
Assert.AreEqual(100, value);
|
|
17
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
18
|
+
|
|
19
|
+
int newValue = dictionary.GetOrAdd(
|
|
20
|
+
"test", () =>
|
|
21
|
+
{
|
|
22
|
+
Assert.Fail("Value Producer should not have been called!");
|
|
23
|
+
return 200;
|
|
24
|
+
});
|
|
25
|
+
Assert.AreEqual(100, newValue);
|
|
26
|
+
|
|
27
|
+
newValue = dictionary.GetOrAdd("test2", () => 300);
|
|
28
|
+
Assert.AreEqual(300, newValue);
|
|
29
|
+
Assert.AreEqual(100, dictionary["test"]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
[Test]
|
|
33
|
+
public void GetOrAddKeyValueProducer()
|
|
34
|
+
{
|
|
35
|
+
Dictionary<string, int> dictionary = new();
|
|
36
|
+
int value = dictionary.GetOrAdd(
|
|
37
|
+
"test", key =>
|
|
38
|
+
{
|
|
39
|
+
Assert.AreEqual("test", key);
|
|
40
|
+
return 100;
|
|
41
|
+
});
|
|
42
|
+
Assert.AreEqual(100, value);
|
|
43
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
44
|
+
|
|
45
|
+
int newValue = dictionary.GetOrAdd(
|
|
46
|
+
"test", key =>
|
|
47
|
+
{
|
|
48
|
+
Assert.Fail("Value Producer should not have been called!");
|
|
49
|
+
return 200;
|
|
50
|
+
});
|
|
51
|
+
Assert.AreEqual(100, newValue);
|
|
52
|
+
|
|
53
|
+
newValue = dictionary.GetOrAdd(
|
|
54
|
+
"test2", key =>
|
|
55
|
+
{
|
|
56
|
+
Assert.AreEqual("test2", key);
|
|
57
|
+
return 300;
|
|
58
|
+
});
|
|
59
|
+
Assert.AreEqual(300, newValue);
|
|
60
|
+
Assert.AreEqual(100, dictionary["test"]);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
[Test]
|
|
64
|
+
public void GetOrElseValue()
|
|
65
|
+
{
|
|
66
|
+
Dictionary<string, int> dictionary = new();
|
|
67
|
+
int value = dictionary.GetOrElse("test", 100);
|
|
68
|
+
Assert.AreEqual(100, value);
|
|
69
|
+
Assert.IsFalse(dictionary.ContainsKey("test"));
|
|
70
|
+
dictionary["test"] = 150;
|
|
71
|
+
value = dictionary.GetOrElse("test", 100);
|
|
72
|
+
Assert.AreEqual(150, value);
|
|
73
|
+
Assert.AreEqual(150, dictionary["test"]);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[Test]
|
|
77
|
+
public void GetOrElseValueProducer()
|
|
78
|
+
{
|
|
79
|
+
Dictionary<string, int> dictionary = new();
|
|
80
|
+
int value = dictionary.GetOrElse("test", () => 100);
|
|
81
|
+
Assert.AreEqual(100, value);
|
|
82
|
+
Assert.IsFalse(dictionary.ContainsKey("test"));
|
|
83
|
+
dictionary["test"] = 150;
|
|
84
|
+
value = dictionary.GetOrElse(
|
|
85
|
+
"test", () =>
|
|
86
|
+
{
|
|
87
|
+
Assert.Fail("Producer should not be called.");
|
|
88
|
+
return 100;
|
|
89
|
+
});
|
|
90
|
+
Assert.AreEqual(150, value);
|
|
91
|
+
Assert.AreEqual(150, dictionary["test"]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[Test]
|
|
95
|
+
public void GetOrElseKeyValueProducer()
|
|
96
|
+
{
|
|
97
|
+
Dictionary<string, int> dictionary = new();
|
|
98
|
+
int value = dictionary.GetOrElse(
|
|
99
|
+
"test", key =>
|
|
100
|
+
{
|
|
101
|
+
Assert.AreEqual("test", key);
|
|
102
|
+
return 100;
|
|
103
|
+
});
|
|
104
|
+
Assert.AreEqual(100, value);
|
|
105
|
+
Assert.IsFalse(dictionary.ContainsKey("test"));
|
|
106
|
+
dictionary["test"] = 150;
|
|
107
|
+
value = dictionary.GetOrElse(
|
|
108
|
+
"test", () =>
|
|
109
|
+
{
|
|
110
|
+
Assert.Fail("Producer should not be called.");
|
|
111
|
+
return 100;
|
|
112
|
+
});
|
|
113
|
+
Assert.AreEqual(150, value);
|
|
114
|
+
Assert.AreEqual(150, dictionary["test"]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[Test]
|
|
118
|
+
public void GetOrAddNew()
|
|
119
|
+
{
|
|
120
|
+
Dictionary<string, List<int>> dictionary = new();
|
|
121
|
+
List<int> value = dictionary.GetOrAdd("test");
|
|
122
|
+
Assert.IsNotNull(value);
|
|
123
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
124
|
+
value.Add(1);
|
|
125
|
+
|
|
126
|
+
List<int> newValue = dictionary.GetOrAdd("test");
|
|
127
|
+
Assert.AreEqual(value, newValue);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
[Test]
|
|
131
|
+
public void GetOrElse()
|
|
132
|
+
{
|
|
133
|
+
IReadOnlyDictionary<string, int> dictionary = new Dictionary<string, int>();
|
|
134
|
+
int value = dictionary.GetOrElse("test", 100);
|
|
135
|
+
Assert.AreEqual(100, value);
|
|
136
|
+
Assert.AreEqual(0, dictionary.Count);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[Test]
|
|
140
|
+
public void AddOrUpdate()
|
|
141
|
+
{
|
|
142
|
+
Dictionary<string, int> dictionary = new();
|
|
143
|
+
int value = dictionary.AddOrUpdate("test", key => 100, (key, existing) => existing + 1);
|
|
144
|
+
Assert.AreEqual(100, value);
|
|
145
|
+
Assert.AreEqual(100, dictionary["test"]);
|
|
146
|
+
int expected = value;
|
|
147
|
+
for (int i = 0; i < 100; ++i)
|
|
148
|
+
{
|
|
149
|
+
value = dictionary.AddOrUpdate("test", key => 100, (key, existing) => existing + 1);
|
|
150
|
+
Assert.AreEqual(++expected, value);
|
|
151
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
value = dictionary.AddOrUpdate("test2", key => 150, (key, existing) => existing + 1);
|
|
155
|
+
Assert.AreEqual(150, value);
|
|
156
|
+
Assert.AreEqual(150, dictionary["test2"]);
|
|
157
|
+
Assert.AreEqual(expected, dictionary["test"]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[Test]
|
|
161
|
+
public void TryAdd()
|
|
162
|
+
{
|
|
163
|
+
Dictionary<string, int> dictionary = new();
|
|
164
|
+
int value = dictionary.TryAdd(
|
|
165
|
+
"test", key =>
|
|
166
|
+
{
|
|
167
|
+
Assert.AreEqual("test", key);
|
|
168
|
+
return 150;
|
|
169
|
+
});
|
|
170
|
+
Assert.AreEqual(150, value);
|
|
171
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
172
|
+
|
|
173
|
+
value = dictionary.TryAdd(
|
|
174
|
+
"test", key =>
|
|
175
|
+
{
|
|
176
|
+
Assert.Fail("Creator should not have been called.");
|
|
177
|
+
return 200;
|
|
178
|
+
});
|
|
179
|
+
Assert.AreEqual(150, value);
|
|
180
|
+
Assert.AreEqual(value, dictionary["test"]);
|
|
181
|
+
|
|
182
|
+
value = dictionary.TryAdd(
|
|
183
|
+
"test2", key =>
|
|
184
|
+
{
|
|
185
|
+
Assert.AreEqual("test2", key);
|
|
186
|
+
return 350;
|
|
187
|
+
});
|
|
188
|
+
Assert.AreEqual(350, value);
|
|
189
|
+
Assert.AreEqual(value, dictionary["test2"]);
|
|
190
|
+
Assert.AreEqual(150, dictionary["test"]);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
[Test]
|
|
194
|
+
public void Merge()
|
|
195
|
+
{
|
|
196
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
197
|
+
{
|
|
198
|
+
["only-on-left"] = 1,
|
|
199
|
+
["both"] = 1,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
203
|
+
{
|
|
204
|
+
["only-on-right"] = 3,
|
|
205
|
+
["both"] = 2,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
Dictionary<string, int> merged = left.Merge(right);
|
|
209
|
+
Assert.AreEqual(3, merged.Count);
|
|
210
|
+
Assert.AreEqual(1, merged["only-on-left"]);
|
|
211
|
+
Assert.AreEqual(2, merged["both"]);
|
|
212
|
+
Assert.AreEqual(3, merged["only-on-right"]);
|
|
213
|
+
|
|
214
|
+
merged = right.Merge(left);
|
|
215
|
+
Assert.AreEqual(3, merged.Count);
|
|
216
|
+
Assert.AreEqual(1, merged["only-on-left"]);
|
|
217
|
+
Assert.AreEqual(1, merged["both"]);
|
|
218
|
+
Assert.AreEqual(3, merged["only-on-right"]);
|
|
219
|
+
|
|
220
|
+
merged = left.Merge(left);
|
|
221
|
+
Assert.AreEqual(2, merged.Count);
|
|
222
|
+
Assert.AreEqual(1, merged["only-on-left"]);
|
|
223
|
+
Assert.AreEqual(1, merged["both"]);
|
|
224
|
+
|
|
225
|
+
merged = right.Merge(right);
|
|
226
|
+
Assert.AreEqual(2, merged.Count);
|
|
227
|
+
Assert.AreEqual(3, merged["only-on-right"]);
|
|
228
|
+
Assert.AreEqual(2, merged["both"]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
[Test]
|
|
232
|
+
public void Difference()
|
|
233
|
+
{
|
|
234
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
235
|
+
{
|
|
236
|
+
["only-on-left"] = 1,
|
|
237
|
+
["both"] = 1,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
241
|
+
{
|
|
242
|
+
["only-on-right"] = 3,
|
|
243
|
+
["both"] = 2,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
Dictionary<string, int> difference = left.Difference(right);
|
|
247
|
+
Assert.AreEqual(2, difference.Count);
|
|
248
|
+
Assert.AreEqual(2, difference["both"]);
|
|
249
|
+
Assert.AreEqual(3, difference["only-on-right"]);
|
|
250
|
+
|
|
251
|
+
difference = right.Difference(left);
|
|
252
|
+
Assert.AreEqual(2, difference.Count);
|
|
253
|
+
Assert.AreEqual(1, difference["both"]);
|
|
254
|
+
Assert.AreEqual(1, difference["only-on-left"]);
|
|
255
|
+
|
|
256
|
+
difference = left.Difference(left);
|
|
257
|
+
Assert.AreEqual(0, difference.Count);
|
|
258
|
+
|
|
259
|
+
difference = right.Difference(right);
|
|
260
|
+
Assert.AreEqual(0, difference.Count);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
[Test]
|
|
264
|
+
public void Reverse()
|
|
265
|
+
{
|
|
266
|
+
IReadOnlyDictionary<string, int> initial = new Dictionary<string, int>()
|
|
267
|
+
{
|
|
268
|
+
["one"] = 1,
|
|
269
|
+
["one-duplicate"] = 1,
|
|
270
|
+
["two"] = 2,
|
|
271
|
+
["three"] = 3,
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
Dictionary<int, string> reversed = initial.Reverse();
|
|
275
|
+
Assert.AreEqual(3, reversed.Count);
|
|
276
|
+
Assert.AreEqual("one-duplicate", reversed[1]);
|
|
277
|
+
Assert.AreEqual("two", reversed[2]);
|
|
278
|
+
Assert.AreEqual("three", reversed[3]);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
[Test]
|
|
282
|
+
public void ToDictionaryFromDictionary()
|
|
283
|
+
{
|
|
284
|
+
IReadOnlyDictionary<string, int> initial = new Dictionary<string, int>()
|
|
285
|
+
{
|
|
286
|
+
["test"] = 1,
|
|
287
|
+
["test2"] = 2,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
Dictionary<string, int> copy = initial.ToDictionary();
|
|
291
|
+
Assert.AreEqual(2, copy.Count);
|
|
292
|
+
Assert.AreEqual(1, copy["test"]);
|
|
293
|
+
Assert.AreEqual(2, copy["test2"]);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
[Test]
|
|
297
|
+
public void ToDictionaryFromEnumerableKeyValuePair()
|
|
298
|
+
{
|
|
299
|
+
IEnumerable<KeyValuePair<string, int>> initial = new Dictionary<string, int>()
|
|
300
|
+
{
|
|
301
|
+
["test"] = 1,
|
|
302
|
+
["test2"] = 2,
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
Dictionary<string, int> copy = initial.ToDictionary();
|
|
306
|
+
Assert.AreEqual(2, copy.Count);
|
|
307
|
+
Assert.AreEqual(1, copy["test"]);
|
|
308
|
+
Assert.AreEqual(2, copy["test2"]);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
[Test]
|
|
312
|
+
public void ToDictionaryFromEnumerableValueTuple()
|
|
313
|
+
{
|
|
314
|
+
IEnumerable<(string, int)> initial = new Dictionary<string, int>()
|
|
315
|
+
{
|
|
316
|
+
["test"] = 1,
|
|
317
|
+
["test2"] = 2,
|
|
318
|
+
}.Select(kvp => (kvp.Key, kvp.Value));
|
|
319
|
+
|
|
320
|
+
Dictionary<string, int> copy = initial.ToDictionary();
|
|
321
|
+
Assert.AreEqual(2, copy.Count);
|
|
322
|
+
Assert.AreEqual(1, copy["test"]);
|
|
323
|
+
Assert.AreEqual(2, copy["test2"]);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
[Test]
|
|
327
|
+
public void ContentEqualsSame()
|
|
328
|
+
{
|
|
329
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
330
|
+
{
|
|
331
|
+
["one"] = 1,
|
|
332
|
+
["two"] = 2,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
336
|
+
{
|
|
337
|
+
["one"] = 1,
|
|
338
|
+
["two"] = 2,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
Assert.IsTrue(left.ContentEquals(right));
|
|
342
|
+
Assert.IsTrue(left.ContentEquals(left));
|
|
343
|
+
Assert.IsTrue(right.ContentEquals(left));
|
|
344
|
+
Assert.IsTrue(right.ContentEquals(right));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
[Test]
|
|
348
|
+
public void ContentEqualsDifferentCount()
|
|
349
|
+
{
|
|
350
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
351
|
+
{
|
|
352
|
+
["one"] = 1,
|
|
353
|
+
["two"] = 2,
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
357
|
+
{
|
|
358
|
+
["one"] = 1,
|
|
359
|
+
["two"] = 2,
|
|
360
|
+
["three"] = 3,
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
Assert.IsFalse(left.ContentEquals(right));
|
|
364
|
+
Assert.IsTrue(left.ContentEquals(left));
|
|
365
|
+
Assert.IsFalse(right.ContentEquals(left));
|
|
366
|
+
Assert.IsTrue(right.ContentEquals(right));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
[Test]
|
|
370
|
+
public void ContentEqualsDifferentValuesSameSize()
|
|
371
|
+
{
|
|
372
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
373
|
+
{
|
|
374
|
+
["one"] = 1,
|
|
375
|
+
["two"] = 2,
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
379
|
+
{
|
|
380
|
+
["one"] = 1,
|
|
381
|
+
["two"] = 20_000,
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
Assert.IsFalse(left.ContentEquals(right));
|
|
385
|
+
Assert.IsTrue(left.ContentEquals(left));
|
|
386
|
+
Assert.IsFalse(right.ContentEquals(left));
|
|
387
|
+
Assert.IsTrue(right.ContentEquals(right));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
[Test]
|
|
391
|
+
public void ContentEqualsDifferentKeysSameSize()
|
|
392
|
+
{
|
|
393
|
+
IReadOnlyDictionary<string, int> left = new Dictionary<string, int>()
|
|
394
|
+
{
|
|
395
|
+
["one"] = 1,
|
|
396
|
+
["two"] = 2,
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
IReadOnlyDictionary<string, int> right = new Dictionary<string, int>()
|
|
400
|
+
{
|
|
401
|
+
["one"] = 1,
|
|
402
|
+
["three"] = 2,
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
Assert.IsFalse(left.ContentEquals(right));
|
|
406
|
+
Assert.IsTrue(left.ContentEquals(left));
|
|
407
|
+
Assert.IsFalse(right.ContentEquals(left));
|
|
408
|
+
Assert.IsTrue(right.ContentEquals(right));
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
[Test]
|
|
412
|
+
public void Deconstruct()
|
|
413
|
+
{
|
|
414
|
+
new KeyValuePair<string, int>("one", 1).Deconstruct(out string key, out int value);
|
|
415
|
+
Assert.AreEqual("one", key);
|
|
416
|
+
Assert.AreEqual(1, value);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|