C#按规则排序含字符串/数字的动态列表异常排查
混合列表排序问题修复
排序规则
列表同时包含整数和字符串两类元素,所有元素按对应权重升序排列:
- 字符串元素权重为自身字符长度
- 整数元素权重为自身数值
问题复现
- 基础测试输入:
[7, "aaa", "a", "cccccccccc", 5] - 基础测试预期输出:
["a", "aaa", 5, 7, "cccccccccc"] - 异常测试输入:
[7, "aaa", "aa", "cccc", "a", 2, 10, 5, "cccccc", "cccccccccccc"] - 异常测试实际错误输出:
["a", 2, "aa", "aaa", 5, "cccc", 7, "cccccc", "cccccccccccc", 10] - 异常测试预期输出:
["a", 2, "aa", "aaa", "cccc", 5, "cccccc", 7, 10, "cccccccccccc"]
原有代码逻辑错误
- 核心思路完全偏离需求:原有实现先把字符串、数字拆成两个列表分别排序,再把数字的自身数值作为插入索引,往排好序的字符串列表中插入元素,本质不是按权重做全局统一排序,属于强行指定插入位置,逻辑从根本上不成立。
- 索引计算逻辑完全错误:每插入一个数字,目标列表的长度就会加1,后续插入操作的索引计算完全没有考虑已插入数字占用的位置;当数字数值大于当前列表长度时,代码走else分支调用
letters.Insert(number),但List<T>.Insert方法要求传入「插入位置、插入元素」两个参数,单参数调用本身就存在语法错误,之前部分用例能跑通只是刚好触发了长度判断分支,属于巧合。 - 类型判断存在缺陷:原有代码用
int.TryParse(i.ToString(), out val)判断元素是否为数字,会把内容为纯数字的字符串(比如"123")误识别为数字,直接通过数据类型判断区分字符串和整数更准确。
修正方案
不需要拆分两类元素分别处理,直接给每个元素计算对应权重后,对全列表做全局排序即可,从根源上避免索引错位问题。
修正后可直接运行的代码:
List<dynamic> aLst = new List<dynamic>(); aLst.Add(7); aLst.Add("aaa"); aLst.Add("aa"); aLst.Add("cccc"); aLst.Add("a"); aLst.Add(2); aLst.Add(10); aLst.Add(5); aLst.Add("cccccc"); aLst.Add("cccccccccccc"); // 按元素权重全局升序排序 var sortedList = aLst.OrderBy(item => { if (item is string str) return str.Length; if (item is int num) return num; throw new ArgumentException("列表包含不支持的元素类型"); }).ToList(); foreach(var value in sortedList) { Console.WriteLine(value); }
运行上述代码即可输出符合预期的排序结果,只要权重计算规则不变,不管后续新增多少元素都不会出现排序错位问题。
内容的提问来源于stack exchange,提问作者user8512043
相关产品推荐
相关产品推荐

