You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#数组调整大小异常 如何正确删除数组0值保留非0元素

问题分析

你的代码存在3处核心错误,直接导致运行结果不符合预期:

  • 数组初始化的遍历逻辑完全错误:foreach (int i in arr)遍历int数组时,循环变量i取到的是数组内存储的元素值,不是位置索引。你刚创建的int数组所有元素默认值都是0,所以这段循环从头到尾都在反复修改arr[0]的值,剩下29个数组位置从来没被赋过随机值,一直是默认0,你写的zeroCounter统计结果从根上就是错的。
  • 结果输出的遍历逻辑也错了:和上面的问题一样,过滤后的数组用foreach遍历的时候,循环变量就是你要输出的非0数字本身,你写arr[i]相当于拿数字当数组索引去取值,轻则取到错误的数,重则直接触发索引越界异常。
  • 存在冗余的错误操作:arr.Where(i => i != 0).ToArray()执行完成后,返回的新数组本来就只包含所有非0元素,长度自动匹配非0元素的总数量,后面调用Array.Resize完全是画蛇添足,再加上你之前zeroCounter的计数本身不准,这步Resize反而可能把已经过滤好的有效元素截掉。
修正后代码
int SIZE = 30;
var rand = new Random();
int[] arr = new int[SIZE];
// 数组赋值用for循环走索引,避免foreach拿不到索引的问题
for (int idx = 0; idx < arr.Length; idx++)
{
    arr[idx] = rand.Next(0, 11);
    Console.Write(arr[idx] + " ");
}
Console.WriteLine();
// 直接用LINQ过滤0值生成新数组,不需要额外计数、不需要Resize
arr = arr.Where(num => num != 0).ToArray();
// 遍历输出直接取循环变量即可,不要把元素当索引用
foreach (int num in arr)
{
    Console.Write(num + " ");
}
可选的无LINQ实现

如果你不想用LINQ的Where方法,也可以手动实现过滤逻辑,本质逻辑一致:

int SIZE = 30;
var rand = new Random();
int[] arr = new int[SIZE];
for (int idx = 0; idx < arr.Length; idx++)
{
    arr[idx] = rand.Next(0, 11);
    Console.Write(arr[idx] + " ");
}
Console.WriteLine();
// 先统计非0元素个数
int nonZeroCount = 0;
foreach (int num in arr)
{
    if (num != 0) nonZeroCount++;
}
// 创建对应长度的新数组,拷贝非0元素
int[] result = new int[nonZeroCount];
int resultIdx = 0;
foreach (int num in arr)
{
    if (num != 0)
    {
        result[resultIdx] = num;
        resultIdx++;
    }
}
// 输出结果
foreach (int num in result)
{
    Console.Write(num + " ");
}

内容的提问来源于stack exchange,提问作者Gleb Shapovalov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:18:14