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

仅排序数组奇数元素:LINQ实现报错问题咨询

问题分析与解决方案

你的代码报错核心原因很明确:你构建的字典dictionary只包含原数组中奇数元素的索引和它们排序后的值。当处理原数组中的偶数元素时,你错误地尝试用该偶数元素的索引去字典中取值——而这个索引根本不在字典的键集合里,直接触发KeyNotFoundException。

另外代码还有个明显错误:最后返回的是new int[1],这完全不符合需求,应该返回处理后的结果数组。

正确实现思路

要实现「仅排序奇数元素,偶数位置不变」,正确逻辑是:

  1. 提取原数组中所有奇数,对它们进行排序;
  2. 遍历原数组,遇到奇数时,从排序后的奇数列表中按顺序取出一个替换进去;遇到偶数则直接保留原值。

修正后的代码(两种写法)

写法1:使用队列(简洁直观)

public class Kata
{
    public static int[] SortArray(int[] array)
    {
        // 将排序后的奇数存入队列,方便按顺序取出
        var sortedOdds = new Queue<int>(array.Where(x => x % 2 == 1).OrderBy(x => x));
        // 遍历原数组,奇数替换为队列头部元素,偶数保留
        return array.Select(x => x % 2 == 1 ? sortedOdds.Dequeue() : x).ToArray();
    }
}

public class Program
{
    static void Main(string[] args)
    {
        // 测试输出:1 3 2 8 5 4
        foreach (var num in Kata.SortArray(new int[] { 5, 3, 2, 8, 1, 4 }))
        {
            Console.Write(num + " ");
        }
    }
}

写法2:使用枚举器(内存更高效)

public class Kata
{
    public static int[] SortArray(int[] array)
    {
        var sortedOddsEnumerator = array.Where(x => x % 2 == 1).OrderBy(x => x).GetEnumerator();
        sortedOddsEnumerator.MoveNext(); // 初始化枚举器到第一个元素

        return array.Select(x => 
        {
            if (x % 2 == 1)
            {
                var currentOdd = sortedOddsEnumerator.Current;
                sortedOddsEnumerator.MoveNext();
                return currentOdd;
            }
            return x;
        }).ToArray();
    }
}

代码说明

  • 队列写法:利用队列「先进先出」的特性,排序后的奇数按顺序存入队列,遍历原数组时遇到奇数就取出队列的第一个元素,正好对应排序后的顺序填充到原奇数位置。
  • 枚举器写法:直接使用LINQ查询的枚举器逐个获取排序后的奇数,避免创建额外集合存储所有奇数,内存占用更低。

两种写法都能完美实现需求:原数组中的偶数位置完全不变,奇数元素按升序排列后回到原来的奇数位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:45:17