C#如何基于自定义顺序列表和数值升序规则对字符串集合进行排序
C# 自定义优先级排序实现方案
你可以通过以下两种方式实现需求,两种方案均能达到你期望的排序效果:
方案1:LINQ 生成新排序集合
该方案不会修改原集合,会返回一个全新的已排序集合,适合需要保留原数据的场景:
using System.Linq; using System.Collections.Generic; // 初始化原始集合与优先级规则 List<string> temp = new List<string> { "Mina 1", "Mina 2", "Planning 3", "Planning 2", "Planning 1", "Planning 4", "Kira 2", "Kira 1" }; List<string> sortPriority = new List<string> { "Planning", "Mina", "Kira" }; // 构建名称优先级映射字典,提升查找效率 Dictionary<string, int> priorityMap = sortPriority .Select((name, index) => new { Name = name, Priority = index }) .ToDictionary(item => item.Name, item => item.Priority); // 执行排序 var sortedList = temp .Select(item => { var parts = item.Split(' ', StringSplitOptions.RemoveEmptyEntries); return new { RawValue = item, NamePart = parts[0], NumPart = int.Parse(parts[1]) }; }) .OrderBy(x => priorityMap[x.NamePart]) // 第一规则:按自定义优先级排序 .ThenBy(x => x.NumPart) // 第二规则:同名称下按数字升序 .Select(x => x.RawValue) .ToList();
方案2:直接修改原集合
该方案使用List.Sort自定义比较器,直接在原集合上做排序,适合不需要保留原数据的场景:
// 沿用方案1中定义的temp、sortPriority、priorityMap temp.Sort((a, b) => { var aParts = a.Split(' ', StringSplitOptions.RemoveEmptyEntries); var bParts = b.Split(' ', StringSplitOptions.RemoveEmptyEntries); // 先比较名称优先级 int priorityCompare = priorityMap[aParts[0]].CompareTo(priorityMap[bParts[0]]); if (priorityCompare != 0) { return priorityCompare; } // 名称一致时比较后缀数字 return int.Parse(aParts[1]).CompareTo(int.Parse(bParts[1])); });
兼容特殊场景的小优化
如果你的原始集合可能出现优先级列表中没有的名称,可以在取优先级时增加判断,将未知名称统一排到末尾:
// 把优先级取值逻辑替换为以下写法即可 priorityMap.TryGetValue(namePart, out int priority) ? priority : int.MaxValue
内容的提问来源于stack exchange,提问作者MinhKhai
相关产品推荐
相关产品推荐

