Skip to content

Commit a198aa4

Browse files
fix up some stuff
1 parent a14445a commit a198aa4

5 files changed

Lines changed: 141 additions & 41 deletions

File tree

CommonExtendedObjectsTests/ExtendedSystemObjectsSetOperation.cs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ public void DifferenceAddsElementsInRangeWhenInverted()
165165
CollectionAssert.AreEquivalent(new List<int> { 1, 2, 3, 4 }, list);
166166
}
167167

168+
/// <summary>
169+
/// Unions the removes elements from range when inverted.
170+
/// </summary>
168171
[TestMethod]
169172
public void UnionRemovesElementsFromRangeWhenInverted()
170173
{
@@ -184,7 +187,7 @@ public void UnionRemovesElementsFromRangeWhenInverted()
184187

185188

186189
/// <summary>
187-
/// Symmetrics the difference retains common elements when inverted.
190+
/// Symmetric difference retains common elements when inverted.
188191
/// </summary>
189192
[TestMethod]
190193
public void SymmetricDifferenceRetainsCommonElementsWhenInverted()
@@ -202,5 +205,90 @@ public void SymmetricDifferenceRetainsCommonElementsWhenInverted()
202205

203206
CollectionAssert.AreEqual(new List<int> { 2, 4 }, list);
204207
}
208+
209+
/// <summary>
210+
/// Removes the fast item in middle removes item and swaps last.
211+
/// </summary>
212+
[TestMethod]
213+
public void RemoveFast_ItemInMiddle_RemovesItemAndSwapsLast()
214+
{
215+
// Arrange
216+
var list = new List<string> { "A", "B", "C", "D" };
217+
218+
// Act
219+
list.RemoveFast("B");
220+
221+
// Assert
222+
Assert.AreEqual(3, list.Count);
223+
Assert.IsFalse(list.Contains("B"));
224+
Assert.AreEqual("D", list[1]); // "D" should have moved to index 1
225+
}
226+
227+
/// <summary>
228+
/// Removes the fast item not found does nothing.
229+
/// </summary>
230+
[TestMethod]
231+
public void RemoveFast_ItemNotFound_DoesNothing()
232+
{
233+
// Arrange
234+
var list = new List<int> { 1, 2, 3 };
235+
236+
// Act
237+
list.RemoveFast(99);
238+
239+
// Assert
240+
Assert.AreEqual(3, list.Count);
241+
}
242+
243+
/// <summary>
244+
/// Removes at fast valid index removes and swaps.
245+
/// </summary>
246+
[TestMethod]
247+
public void RemoveAtFast_ValidIndex_RemovesAndSwaps()
248+
{
249+
// Arrange
250+
var list = new List<int> { 10, 20, 30, 40, 50 };
251+
252+
// Act
253+
list.RemoveAtFast(1); // Removing 20
254+
255+
// Assert
256+
Assert.AreEqual(4, list.Count);
257+
Assert.AreEqual(50, list[1]); // Last item (50) should now be at index 1
258+
}
259+
260+
/// <summary>
261+
/// Removes at fast last index removes correctly.
262+
/// </summary>
263+
[TestMethod]
264+
public void RemoveAtFast_LastIndex_RemovesCorrectly()
265+
{
266+
// Arrange
267+
var list = new List<string> { "X", "Y", "Z" };
268+
269+
// Act
270+
list.RemoveAtFast(2); // Removing "Z"
271+
272+
// Assert
273+
Assert.AreEqual(2, list.Count);
274+
Assert.AreEqual("Y", list[1]);
275+
Assert.IsFalse(list.Contains("Z"));
276+
}
277+
278+
/// <summary>
279+
/// Removes at fast invalid index does not throw.
280+
/// </summary>
281+
[TestMethod]
282+
public void RemoveAtFast_InvalidIndex_DoesNotThrow()
283+
{
284+
// Arrange
285+
var list = new List<int> { 1, 2 };
286+
287+
// Act & Assert (Should not throw exception based on implementation)
288+
list.RemoveAtFast(-1);
289+
list.RemoveAtFast(10);
290+
291+
Assert.AreEqual(2, list.Count);
292+
}
205293
}
206294
}

ExtendedSystemObjects/ExtendedDictionary.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public static bool AddDistinct<TKey, TValue>(this IDictionary<TKey, List<TValue>
111111
/// <param name="key">Unique Key</param>
112112
/// <param name="value">Value to add</param>
113113
[MethodImpl(MethodImplOptions.AggressiveInlining)]
114-
public static void AddDistinct<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value)
114+
public static void AddDistinct<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TKey : notnull
115115
{
116116
dic[key] = value;
117117
}
@@ -126,7 +126,7 @@ public static void AddDistinct<TKey, TValue>(this Dictionary<TKey, TValue> dic,
126126
/// <param name="key">The key of the key-value pair to add.</param>
127127
/// <param name="value">The value of the key-value pair to add.</param>
128128
/// <exception cref="ArgumentException">Thrown if the key or value already exist in the dictionary.</exception>
129-
public static void AddDistinctKeyValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value)
129+
public static void AddDistinctKeyValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TKey : notnull
130130
{
131131
if (dic.ContainsKey(key))
132132
{
@@ -150,7 +150,7 @@ public static void AddDistinctKeyValue<TKey, TValue>(this Dictionary<TKey, TValu
150150
/// <typeparam name="TValue">Internal Value</typeparam>
151151
/// <param name="dic">Internal Target Dictionary</param>
152152
/// <returns>Sorted Dictionary</returns>
153-
public static Dictionary<TKey, TValue> Sort<TKey, TValue>(this Dictionary<TKey, TValue> dic)
153+
public static Dictionary<TKey, TValue> Sort<TKey, TValue>(this Dictionary<TKey, TValue> dic) where TKey : notnull
154154
{
155155
var sortedPairs = dic.OrderBy(pair => pair.Key).ToList();
156156

@@ -172,7 +172,7 @@ public static Dictionary<TKey, TValue> Sort<TKey, TValue>(this Dictionary<TKey,
172172
/// <param name="dic">Internal Target Dictionary</param>
173173
/// <returns>If Dictionary is Null or has zero Elements</returns>
174174
[MethodImpl(MethodImplOptions.AggressiveInlining)]
175-
public static bool IsNullOrEmpty<TKey, TValue>([NotNullWhen(false)] this IDictionary<TKey, TValue> dic)
175+
public static bool IsNullOrEmpty<TKey, TValue>([NotNullWhen(false)] this IDictionary<TKey, TValue>? dic)
176176
{
177177
if (dic == null)
178178
{
@@ -190,7 +190,7 @@ public static bool IsNullOrEmpty<TKey, TValue>([NotNullWhen(false)] this IDictio
190190
/// <returns>False if one is missing. <see cref="bool" />.</returns>
191191
/// <typeparam name="TKey">Internal Key</typeparam>
192192
/// <typeparam name="TValue">Internal Value</typeparam>
193-
public static bool ContainsKeys<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<TKey> enumerable)
193+
public static bool ContainsKeys<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<TKey> enumerable) where TKey : notnull
194194
{
195195
return enumerable.All(dic.ContainsKey);
196196
}
@@ -202,7 +202,7 @@ public static bool ContainsKeys<TKey, TValue>(this Dictionary<TKey, TValue> dic,
202202
/// <typeparam name="TValue">Internal Value</typeparam>
203203
/// <param name="dic">Internal Target Dictionary</param>
204204
/// <returns>If Dictionary has distinct Values</returns>
205-
public static bool IsValueDistinct<TKey, TValue>(this Dictionary<TKey, TValue> dic)
205+
public static bool IsValueDistinct<TKey, TValue>(this Dictionary<TKey, TValue> dic) where TKey : notnull
206206
{
207207
var uniqueValues = new HashSet<TValue>();
208208

@@ -292,7 +292,7 @@ public static Dictionary<TKey, TValue> GetDictionaryByValues<TKey, TValue>(this
292292
/// <typeparam name="TValue">Internal Value</typeparam>
293293
/// <param name="dic">Internal Target Dictionary</param>
294294
/// <returns>Clone of the Input Dictionary</returns>
295-
public static Dictionary<TKey, TValue> Clone<TKey, TValue>(this IDictionary<TKey, TValue> dic)
295+
public static Dictionary<TKey, TValue>? Clone<TKey, TValue>(this IDictionary<TKey, TValue> dic) where TKey : notnull
296296
{
297297
return dic?.ToDictionary(dctClone => dctClone.Key, dctClone => dctClone.Value);
298298
}
@@ -347,7 +347,7 @@ public static bool Reduce<TKey, TValue>(this Dictionary<TKey, TValue> dic)
347347
/// A list with the Key as id
348348
/// </returns>
349349
public static List<TValue> ToListId<TId, TValue>(this Dictionary<TId, TValue> dic)
350-
where TValue : IIdHandling<TId>
350+
where TValue : IIdHandling<TId> where TId : notnull
351351
{
352352
var lst = new List<TValue>();
353353

ExtendedSystemObjects/ExtendedList.cs

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public static class ExtendedList
2929
/// <summary>
3030
/// Check if a List is Null or just Empty
3131
/// </summary>
32-
/// <typeparam name="TValue">Generic data Type</typeparam>
32+
/// <typeparam name="TValue">Generic Object Type</typeparam>
3333
/// <param name="lst">List we want to check</param>
3434
/// <returns>Empty or not</returns>
3535
[MethodImpl(MethodImplOptions.AggressiveInlining)]
36-
public static bool IsNullOrEmpty<TValue>([NotNullWhen(false)] this ICollection<TValue> lst)
36+
public static bool IsNullOrEmpty<TValue>([NotNullWhen(false)] this ICollection<TValue>? lst)
3737
{
3838
if (lst == null)
3939
{
@@ -46,7 +46,7 @@ public static bool IsNullOrEmpty<TValue>([NotNullWhen(false)] this ICollection<T
4646
/// <summary>
4747
/// Add Element at the first Entry
4848
/// </summary>
49-
/// <typeparam name="TValue">Generic data Type</typeparam>
49+
/// <typeparam name="TValue">Generic Object Type</typeparam>
5050
/// <param name="lst">List we want to add to</param>
5151
/// <param name="item">item we will replace or add</param>
5252
public static void AddFirst<TValue>(this List<TValue> lst, TValue item)
@@ -57,7 +57,23 @@ public static void AddFirst<TValue>(this List<TValue> lst, TValue item)
5757
}
5858

5959
/// <summary>
60-
/// Removes the fast.
60+
/// Only works with equal and Implemented IEquality Interface
61+
/// </summary>
62+
/// <typeparam name="TValue">Generic Object Type</typeparam>
63+
/// <param name="lst">List we want to add to</param>
64+
/// <param name="item">item we will replace or add</param>
65+
/// <returns>if [true] item was added, else [false]</returns>
66+
public static bool AddDistinct<TValue>(this List<TValue> lst, TValue item)
67+
{
68+
if (lst.Contains(item)) return false;
69+
70+
lst.Add(item);
71+
return true;
72+
}
73+
74+
/// <summary>
75+
/// Removes element from ist fast.
76+
/// Destroys order though.
6177
/// </summary>
6278
/// <typeparam name="TValue">Generic data Type</typeparam>
6379
/// <param name="list">The list.</param>
@@ -76,28 +92,24 @@ public static void RemoveFast<TValue>(this List<TValue> list, TValue item)
7692
list.RemoveAt(lastIndex);
7793
}
7894

79-
8095
/// <summary>
81-
/// Only works with equal and Implemented IEquality Interface
96+
/// Removes element at index fast by swapping with the last element.
97+
/// Destroys order.
8298
/// </summary>
83-
/// <typeparam name="TValue">Generic data Type</typeparam>
84-
/// <param name="lst">List we want to add to</param>
85-
/// <param name="item">item we will replace or add</param>
86-
/// <returns>if [true] item was added, else [false]</returns>
87-
public static bool AddDistinct<TValue>(this List<TValue> lst, TValue item)
99+
/// <typeparam name="TValue">The type of the value.</typeparam>
100+
/// <param name="list">The list.</param>
101+
/// <param name="index">The index.</param>
102+
public static void RemoveAtFast<TValue>(this List<TValue> list, int index)
88103
{
89-
var hashSet = new HashSet<TValue>(lst);
104+
if (index < 0 || index >= list.Count) return;
90105

91-
// Check if the item already exists in the HashSet
92-
if (hashSet.Contains(item))
93-
{
94-
return false; // Item already exists, no need to add
95-
}
106+
int lastIndex = list.Count - 1;
96107

97-
// Add the item to the list since it doesn't already exist
98-
lst.Add(item);
108+
// Move the last element into the slot of the element to remove
109+
list[index] = list[lastIndex];
99110

100-
return true;
111+
// Remove the now-redundant last element
112+
list.RemoveAt(lastIndex);
101113
}
102114

103115
/// <summary>
@@ -106,7 +118,7 @@ public static bool AddDistinct<TValue>(this List<TValue> lst, TValue item)
106118
/// <typeparam name="TValue">The type of the value.</typeparam>
107119
/// <param name="lst">The List.</param>
108120
/// <returns>A Dictionary from a list with int as the key</returns>
109-
public static Dictionary<int, TValue> ToDictionary<TValue>(this IEnumerable<TValue> lst)
121+
public static Dictionary<int, TValue>? ToDictionary<TValue>(this IEnumerable<TValue> lst)
110122
{
111123
var index = 0;
112124
return lst?.ToDictionary(_ => index++);
@@ -115,7 +127,7 @@ public static Dictionary<int, TValue> ToDictionary<TValue>(this IEnumerable<TVal
115127
/// <summary>
116128
/// Add contents of another sequence to the base list, ensuring no duplicates
117129
/// </summary>
118-
/// <typeparam name="TValue">Generic data Type</typeparam>
130+
/// <typeparam name="TValue">Generic Object Type</typeparam>
119131
/// <param name="lst">Base list we add to</param>
120132
/// <param name="range">Sequence with elements we want to add</param>
121133
/// <param name="invert">optional parameter invert result</param>
@@ -137,7 +149,7 @@ public static void Union<TValue>(this List<TValue> lst, IEnumerable<TValue> rang
137149
/// <summary>
138150
/// Add contents of another sequence to the base list, ensuring no duplicates
139151
/// </summary>
140-
/// <typeparam name="TValue">Generic data Type</typeparam>
152+
/// <typeparam name="TValue">Generic Object Type</typeparam>
141153
/// <param name="lst">Base list we add to</param>
142154
/// <param name="range">Sequence with elements we want to add</param>
143155
/// <param name="invert">If true, removes elements instead of adding them</param>
@@ -161,7 +173,7 @@ public static void Difference<TValue>(this List<TValue> lst, IEnumerable<TValue>
161173
/// <summary>
162174
/// Keep only elements present in both the base list and another sequence
163175
/// </summary>
164-
/// <typeparam name="TValue">Generic data Type</typeparam>
176+
/// <typeparam name="TValue">Generic Object Type</typeparam>
165177
/// <param name="lst">Base list to filter</param>
166178
/// <param name="range">Sequence with elements to retain</param>
167179
/// <param name="invert">If true, keeps elements not present in both sequences</param>
@@ -186,7 +198,7 @@ public static void Intersection<TValue>(this List<TValue> lst, IEnumerable<TValu
186198
/// <summary>
187199
/// Keep only elements that are in either the base list or another sequence but not in both
188200
/// </summary>
189-
/// <typeparam name="TValue">Generic data Type</typeparam>
201+
/// <typeparam name="TValue">Generic Object Type</typeparam>
190202
/// <param name="lst">Base list to modify</param>
191203
/// <param name="range">Sequence with elements to compare</param>
192204
/// <param name="invert">If true, keeps elements that are in both sequences</param>
@@ -214,10 +226,10 @@ public static void SymmetricDifference<TValue>(this List<TValue> lst, IEnumerabl
214226
/// Try to Clone a List
215227
/// Here we abuse the IEnumerable ToList Method
216228
/// </summary>
217-
/// <typeparam name="TValue">Generic data Type</typeparam>
229+
/// <typeparam name="TValue">Generic Object Type</typeparam>
218230
/// <param name="lst">IEnumerable</param>
219231
/// <returns>Clone of the Input IEnumerable</returns>
220-
public static List<TValue> Clone<TValue>(this IEnumerable<TValue> lst)
232+
public static List<TValue>? Clone<TValue>(this IEnumerable<TValue>? lst)
221233
{
222234
return lst?.ToList();
223235
}
@@ -277,7 +289,7 @@ public static bool Equal<TValue>(this List<TValue> lst, List<TValue> compare, En
277289
/// <summary>
278290
/// Chunks a list by a certain amount.
279291
/// </summary>
280-
/// <typeparam name="TValue">Generic data Type</typeparam>
292+
/// <typeparam name="TValue">Generic Object Type</typeparam>
281293
/// <param name="source">The source.</param>
282294
/// <param name="chunkSize">Size of the chunk.</param>
283295
/// <returns>List split into chunks</returns>
@@ -324,8 +336,8 @@ public static void Shuffle<T>(this IList<T> lst)
324336
/// <returns>
325337
/// Dictionary with an conversion from the attribute Id as Key
326338
/// </returns>
327-
public static Dictionary<TId, TValue> ToDictionaryId<TValue, TId>(this IList<TValue> lst)
328-
where TValue : IIdHandling<TId>
339+
public static Dictionary<TId, TValue> ToDictionaryId<TValue, TId>(this IEnumerable<TValue> lst)
340+
where TValue : IIdHandling<TId> where TId : notnull
329341
{
330342
var dct = new Dictionary<TId, TValue>();
331343

ImageCompare/ImageDuplication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ internal static class ImageDuplication
3737
/// <summary>
3838
/// The Temp path dictionary
3939
/// </summary>
40-
private static Dictionary<int, string> Translator { get; set; }
40+
private static Dictionary<int, string>? Translator { get; set; }
4141

4242
/// <summary>
4343
/// Find all duplicate images in a folder, and possibly subfolders

ImageCompare/ImageSimilarity.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal static class ImageSimilarity
2727
/// <summary>
2828
/// The Temp path dictionary
2929
/// </summary>
30-
private static Dictionary<int, string> Translator { get; set; }
30+
private static Dictionary<int, string>? Translator { get; set; }
3131

3232
/// <summary>
3333
/// Find all similar images in a folder, and possibly subfolders

0 commit comments

Comments
 (0)