// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! namespace Admin.NET.Core; /// /// 堆栈扩展方法 /// public static class StackExtensions { /// /// 批量入栈 /// /// 堆栈元素类型 /// 堆栈实例 /// 要入栈的元素集合 /// 堆栈或元素集合为空时抛出 public static void PushRange(this Stack stack, IEnumerable items) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(items); foreach (var item in items) { stack.Push(item); } } /// /// 批量入栈(保持集合的原始顺序) /// /// 堆栈元素类型 /// 堆栈实例 /// 要入栈的元素集合 /// 堆栈或元素集合为空时抛出 public static void PushRangeReversed(this Stack stack, IEnumerable items) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(items); // 反转顺序入栈,使得弹出时保持原始顺序 var itemsArray = items.ToArray(); for (var i = itemsArray.Length - 1; i >= 0; i--) { stack.Push(itemsArray[i]); } } /// /// 批量出栈 /// /// 堆栈元素类型 /// 堆栈实例 /// 要出栈的元素数量 /// 出栈的元素集合 /// 堆栈为空时抛出 /// 数量小于0或大于堆栈长度时抛出 public static IEnumerable PopRange(this Stack stack, int count) { ArgumentNullException.ThrowIfNull(stack); if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能小于0"); } if (count > stack.Count) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能大于堆栈长度"); } var result = new List(count); for (var i = 0; i < count; i++) { result.Add(stack.Pop()); } return result; } /// /// 尝试出栈多个元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 要出栈的元素数量 /// 出栈的元素集合 /// 是否成功出栈指定数量的元素 public static bool TryPopRange(this Stack stack, int count, out IEnumerable items) { items = []; if (count < 0 || count > stack.Count) { return false; } var result = new List(count); var tempItems = new List(); for (var i = 0; i < count; i++) { if (stack.TryPop(out var item)) { result.Add(item); tempItems.Add(item); } else { // 恢复已出栈的元素 for (var j = tempItems.Count - 1; j >= 0; j--) { stack.Push(tempItems[j]); } return false; } } items = result; return true; } /// /// 清空堆栈并返回所有元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 堆栈中的所有元素 /// 堆栈为空时抛出 public static IEnumerable DrainToList(this Stack stack) { ArgumentNullException.ThrowIfNull(stack); var result = new List(stack.Count); while (stack.Count > 0) { result.Add(stack.Pop()); } return result; } /// /// 安全地查看堆栈顶部元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 堆栈顶部元素 /// 是否成功查看 public static bool TryPeek(this Stack stack, out T? item) { item = default; if (stack.Count == 0) { return false; } item = stack.Peek(); return true; } /// /// 安全地查看多个顶部元素(不出栈) /// /// 堆栈元素类型 /// 堆栈实例 /// 要查看的元素数量 /// 顶部指定数量的元素 /// 堆栈为空时抛出 /// 数量小于0或大于堆栈长度时抛出 public static IEnumerable PeekRange(this Stack stack, int count) { ArgumentNullException.ThrowIfNull(stack); if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能小于0"); } if (count > stack.Count) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能大于堆栈长度"); } var items = stack.ToArray(); return items.Take(count); } /// /// 检查堆栈是否为空 /// /// 堆栈元素类型 /// 堆栈实例 /// 堆栈是否为空 public static bool IsEmpty(this Stack stack) { return stack?.Count == 0; } /// /// 检查堆栈是否不为空 /// /// 堆栈元素类型 /// 堆栈实例 /// 堆栈是否不为空 public static bool IsNotEmpty(this Stack stack) { return stack?.Count > 0; } /// /// 将堆栈转换为数组,保持堆栈顺序 /// /// 堆栈元素类型 /// 堆栈实例 /// 包含堆栈所有元素的数组 /// 堆栈为空时抛出 public static T[] ToArrayPreserveOrder(this Stack stack) { ArgumentNullException.ThrowIfNull(stack); return [.. stack]; } /// /// 复制堆栈 /// /// 堆栈元素类型 /// 原堆栈 /// 复制的新堆栈 /// 堆栈为空时抛出 public static Stack Clone(this Stack stack) { ArgumentNullException.ThrowIfNull(stack); // 保持原始堆栈的顺序 var items = stack.ToArray(); return new Stack(items); } /// /// 查找堆栈中是否包含满足条件的元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 匹配条件 /// 是否包含满足条件的元素 /// 堆栈或条件为空时抛出 public static bool Contains(this Stack stack, Func predicate) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(predicate); return stack.Any(predicate); } /// /// 统计堆栈中满足条件的元素数量 /// /// 堆栈元素类型 /// 堆栈实例 /// 匹配条件 /// 满足条件的元素数量 /// 堆栈或条件为空时抛出 public static int Count(this Stack stack, Func predicate) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(predicate); return stack.Count(predicate); } /// /// 对堆栈中的每个元素执行指定操作(从顶部到底部) /// /// 堆栈元素类型 /// 堆栈实例 /// 要执行的操作 /// 堆栈或操作为空时抛出 public static void ForEach(this Stack stack, Action action) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(action); foreach (var item in stack) { action(item); } } /// /// 对堆栈中的每个元素执行指定操作(带索引,从顶部到底部) /// /// 堆栈元素类型 /// 堆栈实例 /// 要执行的操作,参数为元素和索引 /// 堆栈或操作为空时抛出 public static void ForEach(this Stack stack, Action action) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(action); var index = 0; foreach (var item in stack) { action(item, index++); } } /// /// 创建一个新堆栈,包含满足条件的元素 /// /// 堆栈元素类型 /// 原堆栈 /// 筛选条件 /// 包含满足条件元素的新堆栈 /// 堆栈或条件为空时抛出 public static Stack Where(this Stack stack, Func predicate) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(predicate); var filteredItems = stack.Where(predicate).ToArray(); return new Stack(filteredItems); } /// /// 创建一个新堆栈,包含转换后的元素 /// /// 原堆栈元素类型 /// 目标堆栈元素类型 /// 原堆栈 /// 转换函数 /// 包含转换后元素的新堆栈 /// 堆栈或转换函数为空时抛出 public static Stack Select(this Stack stack, Func selector) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(selector); var transformedItems = stack.Select(selector).ToArray(); return new Stack(transformedItems); } /// /// 反转堆栈中的元素顺序 /// /// 堆栈元素类型 /// 堆栈实例 /// 堆栈为空时抛出 public static void Reverse(this Stack stack) { ArgumentNullException.ThrowIfNull(stack); if (stack.Count <= 1) { return; } var items = new T[stack.Count]; var index = 0; while (stack.Count > 0) { items[index++] = stack.Pop(); } foreach (var item in items) { stack.Push(item); } } /// /// 获取堆栈的深度副本(递归反转以保持原始顺序) /// /// 堆栈元素类型 /// 原堆栈 /// 深度副本的新堆栈 /// 堆栈为空时抛出 public static Stack DeepClone(this Stack stack) { ArgumentNullException.ThrowIfNull(stack); var tempStack = new Stack(); var result = new Stack(); // 第一次反转到临时堆栈 foreach (var item in stack) { tempStack.Push(item); } // 第二次反转到结果堆栈,恢复原始顺序 while (tempStack.Count > 0) { result.Push(tempStack.Pop()); } return result; } /// /// 限制堆栈的最大长度,超出时移除底部元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 最大长度 /// 堆栈为空时抛出 /// 最大长度小于0时抛出 public static void LimitSize(this Stack stack, int maxSize) { ArgumentNullException.ThrowIfNull(stack); if (maxSize < 0) { throw new ArgumentOutOfRangeException(nameof(maxSize), "最大长度不能小于0"); } if (stack.Count <= maxSize) { return; } // 将堆栈内容转移到数组,保留最新的maxSize个元素 var items = stack.ToArray(); stack.Clear(); // 重新入栈最新的maxSize个元素 for (var i = Math.Min(maxSize - 1, items.Length - 1); i >= 0; i--) { stack.Push(items[i]); } } /// /// 安全地入栈元素,如果堆栈已满则移除底部元素 /// /// 堆栈元素类型 /// 堆栈实例 /// 要入栈的元素 /// 堆栈最大长度 /// 被移除的元素(如果有) /// 堆栈为空时抛出 /// 最大长度小于1时抛出 public static T? PushWithLimit(this Stack stack, T item, int maxSize) { ArgumentNullException.ThrowIfNull(stack); if (maxSize < 1) { throw new ArgumentOutOfRangeException(nameof(maxSize), "最大长度不能小于1"); } T? removedItem = default; if (stack.Count >= maxSize) { // 将所有元素转移到数组 var items = stack.ToArray(); stack.Clear(); // 保存被移除的底部元素 if (items.Length > 0) { removedItem = items[items.Length - 1]; } // 重新入栈,跳过底部元素 for (var i = Math.Min(maxSize - 2, items.Length - 2); i >= 0; i--) { stack.Push(items[i]); } } stack.Push(item); return removedItem; } /// /// 检查是否所有元素都满足条件 /// /// 堆栈元素类型 /// 堆栈实例 /// 匹配条件 /// 是否所有元素都满足条件 /// 堆栈或条件为空时抛出 public static bool All(this Stack stack, Func predicate) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(predicate); return stack.All(predicate); } /// /// 检查是否至少有一个元素满足条件 /// /// 堆栈元素类型 /// 堆栈实例 /// 匹配条件 /// 是否至少有一个元素满足条件 /// 堆栈或条件为空时抛出 public static bool Any(this Stack stack, Func predicate) { ArgumentNullException.ThrowIfNull(stack); ArgumentNullException.ThrowIfNull(predicate); return stack.Any(predicate); } /// /// 合并两个堆栈(第二个堆栈的元素将位于顶部) /// /// 堆栈元素类型 /// 第一个堆栈 /// 第二个堆栈 /// 合并后的新堆栈 /// 任一堆栈为空时抛出 public static Stack Concat(this Stack first, Stack second) { ArgumentNullException.ThrowIfNull(first); ArgumentNullException.ThrowIfNull(second); var result = new Stack(); // 先添加第一个堆栈的元素(从底部到顶部) var firstItems = first.ToArray(); for (var i = firstItems.Length - 1; i >= 0; i--) { result.Push(firstItems[i]); } // 再添加第二个堆栈的元素(从底部到顶部) var secondItems = second.ToArray(); for (var i = secondItems.Length - 1; i >= 0; i--) { result.Push(secondItems[i]); } return result; } }