StackExtensions.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. namespace Terminal.Gui;
  2. /// <summary>Extension of <see cref="Stack{T}"/> helper to work with specific <see cref="IEqualityComparer{T}"/></summary>
  3. public static class StackExtensions
  4. {
  5. /// <summary>Check if the stack object contains the value to find.</summary>
  6. /// <typeparam name="T">The stack object type.</typeparam>
  7. /// <param name="stack">The stack object.</param>
  8. /// <param name="valueToFind">Value to find.</param>
  9. /// <param name="comparer">The comparison object.</param>
  10. /// <returns><c>true</c> If the value was found.<c>false</c> otherwise.</returns>
  11. public static bool Contains<T> (this Stack<T> stack, T valueToFind, IEqualityComparer<T> comparer = null)
  12. {
  13. comparer = comparer ?? EqualityComparer<T>.Default;
  14. foreach (T obj in stack)
  15. {
  16. if (comparer.Equals (obj, valueToFind))
  17. {
  18. return true;
  19. }
  20. }
  21. return false;
  22. }
  23. /// <summary>Find all duplicates stack objects values.</summary>
  24. /// <typeparam name="T">The stack object type.</typeparam>
  25. /// <param name="stack">The stack object.</param>
  26. /// <param name="comparer">The comparison object.</param>
  27. /// <returns>The duplicates stack object.</returns>
  28. public static Stack<T> FindDuplicates<T> (this Stack<T> stack, IEqualityComparer<T> comparer = null)
  29. {
  30. comparer = comparer ?? EqualityComparer<T>.Default;
  31. Stack<T> dup = new ();
  32. T [] stackArr = stack.ToArray ();
  33. for (var i = 0; i < stackArr.Length; i++)
  34. {
  35. T value = stackArr [i];
  36. for (int j = i + 1; j < stackArr.Length; j++)
  37. {
  38. T valueToFind = stackArr [j];
  39. if (comparer.Equals (value, valueToFind) && !Contains (dup, valueToFind))
  40. {
  41. dup.Push (value);
  42. }
  43. }
  44. }
  45. return dup;
  46. }
  47. /// <summary>Move the first stack object value to the end.</summary>
  48. /// <typeparam name="T">The stack object type.</typeparam>
  49. /// <param name="stack">The stack object.</param>
  50. public static void MoveNext<T> (this Stack<T> stack)
  51. {
  52. Stack<T> temp = new ();
  53. T last = stack.Pop ();
  54. while (stack.Count > 0)
  55. {
  56. T value = stack.Pop ();
  57. temp.Push (value);
  58. }
  59. temp.Push (last);
  60. while (temp.Count > 0)
  61. {
  62. stack.Push (temp.Pop ());
  63. }
  64. }
  65. /// <summary>Move the last stack object value to the top.</summary>
  66. /// <typeparam name="T">The stack object type.</typeparam>
  67. /// <param name="stack">The stack object.</param>
  68. public static void MovePrevious<T> (this Stack<T> stack)
  69. {
  70. Stack<T> temp = new ();
  71. T first = default;
  72. while (stack.Count > 0)
  73. {
  74. T value = stack.Pop ();
  75. temp.Push (value);
  76. if (stack.Count == 1)
  77. {
  78. first = stack.Pop ();
  79. }
  80. }
  81. while (temp.Count > 0)
  82. {
  83. stack.Push (temp.Pop ());
  84. }
  85. stack.Push (first);
  86. }
  87. /// <summary>Move the stack object value to the index.</summary>
  88. /// <typeparam name="T">The stack object type.</typeparam>
  89. /// <param name="stack">The stack object.</param>
  90. /// <param name="valueToMove">Value to move.</param>
  91. /// <param name="index">The index where to move.</param>
  92. /// <param name="comparer">The comparison object.</param>
  93. public static void MoveTo<T> (
  94. this Stack<T> stack,
  95. T valueToMove,
  96. int index = 0,
  97. IEqualityComparer<T> comparer = null
  98. )
  99. {
  100. if (index < 0)
  101. {
  102. return;
  103. }
  104. comparer = comparer ?? EqualityComparer<T>.Default;
  105. Stack<T> temp = new ();
  106. var toMove = default (T);
  107. int stackCount = stack.Count;
  108. var count = 0;
  109. while (stack.Count > 0)
  110. {
  111. T value = stack.Pop ();
  112. if (comparer.Equals (value, valueToMove))
  113. {
  114. toMove = value;
  115. break;
  116. }
  117. temp.Push (value);
  118. count++;
  119. }
  120. var idx = 0;
  121. while (stack.Count < stackCount)
  122. {
  123. if (count - idx == index)
  124. {
  125. stack.Push (toMove);
  126. }
  127. else
  128. {
  129. stack.Push (temp.Pop ());
  130. }
  131. idx++;
  132. }
  133. }
  134. /// <summary>Replaces a stack object values that match with the value to replace.</summary>
  135. /// <typeparam name="T">The stack object type.</typeparam>
  136. /// <param name="stack">The stack object.</param>
  137. /// <param name="valueToReplace">Value to replace.</param>
  138. /// <param name="valueToReplaceWith">Value to replace with to what matches the value to replace.</param>
  139. /// <param name="comparer">The comparison object.</param>
  140. public static void Replace<T> (
  141. this Stack<T> stack,
  142. T valueToReplace,
  143. T valueToReplaceWith,
  144. IEqualityComparer<T> comparer = null
  145. )
  146. {
  147. comparer = comparer ?? EqualityComparer<T>.Default;
  148. Stack<T> temp = new ();
  149. while (stack.Count > 0)
  150. {
  151. T value = stack.Pop ();
  152. if (comparer.Equals (value, valueToReplace))
  153. {
  154. stack.Push (valueToReplaceWith);
  155. break;
  156. }
  157. temp.Push (value);
  158. }
  159. while (temp.Count > 0)
  160. {
  161. stack.Push (temp.Pop ());
  162. }
  163. }
  164. /// <summary>Swap two stack objects values that matches with the both values.</summary>
  165. /// <typeparam name="T">The stack object type.</typeparam>
  166. /// <param name="stack">The stack object.</param>
  167. /// <param name="valueToSwapFrom">Value to swap from.</param>
  168. /// <param name="valueToSwapTo">Value to swap to.</param>
  169. /// <param name="comparer">The comparison object.</param>
  170. public static void Swap<T> (
  171. this Stack<T> stack,
  172. T valueToSwapFrom,
  173. T valueToSwapTo,
  174. IEqualityComparer<T> comparer = null
  175. )
  176. {
  177. comparer = comparer ?? EqualityComparer<T>.Default;
  178. int index = stack.Count - 1;
  179. T [] stackArr = new T [stack.Count];
  180. while (stack.Count > 0)
  181. {
  182. T value = stack.Pop ();
  183. if (comparer.Equals (value, valueToSwapFrom))
  184. {
  185. stackArr [index] = valueToSwapTo;
  186. }
  187. else if (comparer.Equals (value, valueToSwapTo))
  188. {
  189. stackArr [index] = valueToSwapFrom;
  190. }
  191. else
  192. {
  193. stackArr [index] = value;
  194. }
  195. index--;
  196. }
  197. for (var i = 0; i < stackArr.Length; i++)
  198. {
  199. stack.Push (stackArr [i]);
  200. }
  201. }
  202. }