如何自定义IComparer实现InventoryPick数据的关联分组排序?
自定义IComparer实现Kit项与关联普通项相邻排序
问题描述
我已经实现了一个继承自IComparer<InventoryPick>的MyCompare类,当前排序结果如下:
itemnumber kitnumber BABY-KIT-my-NK NULL x-KIT-my-NK NULL item1 BABY-KIT-my item2 x-KIT-my item3 x-KIT-my
但期望实现如下排序效果:
itemnumber kitnumber BABY-KIT-my-NK NULL item1 BABY-KIT-my x-KIT-my-NK NULL item2 x-KIT-my item3 x-KIT-my
排序规则
- itemnumber以
-NK结尾的视为Kit项,其kitnumber恒为NULL; - itemnumber不含
-NK的为普通项,若普通项的kitnumber与Kit项的itemnumber去掉-NK后缀后匹配,需与对应Kit项相邻排列,方便统一拣选。
需要调整MyCompare类的Compare方法逻辑,实现上述自定义排序需求。
解决方案
核心思路
为每个InventoryPick生成包含分组键和是否为Kit项的排序标识:
- 以Kit项的基准名称(去掉
-NK的部分)作为分组依据,确保关联的Kit项和普通项归为同一组 - 同一组内,Kit项优先排在前面,普通项紧随其后
- 不同组之间按基准名称的字符串顺序排序
代码实现
public class MyCompare : IComparer<InventoryPick> { public int Compare(InventoryPick x, InventoryPick y) { var xSortKey = GenerateSortKey(x); var ySortKey = GenerateSortKey(y); // 先按分组键排序,确保同组项排在一起 int groupComparison = string.Compare(xSortKey.GroupId, ySortKey.GroupId, StringComparison.OrdinalIgnoreCase); if (groupComparison != 0) { return groupComparison; } // 同组内Kit项排在普通项之前(bool排序中true > false,取反实现Kit项优先) return xSortKey.IsKit.CompareTo(ySortKey.IsKit) * -1; } private SortKey GenerateSortKey(InventoryPick pick) { bool isKitItem = !string.IsNullOrWhiteSpace(pick.itemnumber) && pick.itemnumber.EndsWith("-NK", StringComparison.OrdinalIgnoreCase); string groupId; if (isKitItem) { // Kit项的分组ID为去掉-NK后缀的itemnumber groupId = pick.itemnumber.Substring(0, pick.itemnumber.Length - 3); } else { // 普通项的分组ID为其关联的kitnumber groupId = pick.kitnumber ?? string.Empty; } return new SortKey { GroupId = groupId, IsKit = isKitItem }; } // 辅助类存储排序所需的关键信息 private class SortKey { public string GroupId { get; set; } public bool IsKit { get; set; } } }
逻辑说明
- GenerateSortKey方法:
- 判断当前项是否为Kit项(itemnumber以
-NK结尾) - 为Kit项生成分组ID:去掉
-NK后缀的itemnumber - 为普通项生成分组ID:直接使用其
kitnumber值(关联的Kit基准名称)
- 判断当前项是否为Kit项(itemnumber以
- Compare方法:
- 优先比较分组ID,确保同一关联组的项排在一起
- 同一组内,通过反转bool类型的排序结果,让Kit项排在普通项之前
- 字符串比较使用
StringComparison.OrdinalIgnoreCase实现大小写不敏感排序,若需要严格区分大小写,可移除该参数。
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

