如何使用IComparer实现两个IEnumerable序列的字典序比较方法
C# 泛型序列字典序比较方法实现
核心逻辑
字典序比较的规则可以拆解为3步:
- 按索引依次对比两个序列的同位置元素,第一个不相等元素的比较结果,就是整体序列的最终比较结果
- 如果已遍历的所有元素都相等,长度更短的序列字典序更靠前
- 如果两个序列长度相同且所有元素都相等,返回0
完整代码实现
public static int CompareEnumerables<T>(IEnumerable<T> xs, IEnumerable<T> ys, IComparer<T> comp) { // 空引用边界处理,空序列默认比非空序列更靠前 if (xs == null && ys == null) return 0; if (xs == null) return -1; if (ys == null) return 1; // 用迭代器遍历,适配任意IEnumerable实现,不需要提前加载全量序列 using var enumeratorX = xs.GetEnumerator(); using var enumeratorY = ys.GetEnumerator(); while (true) { bool xHasNext = enumeratorX.MoveNext(); bool yHasNext = enumeratorY.MoveNext(); // 两个序列都遍历完成,完全相等 if (!xHasNext && !yHasNext) return 0; // x序列先遍历完,长度更短,字典序更靠前 if (!xHasNext) return -1; // y序列先遍历完,x长度更长,字典序更靠后 if (!yHasNext) return 1; // 比较当前位置元素 int elementCompareResult = comp.Compare(enumeratorX.Current, enumeratorY.Current); if (elementCompareResult != 0) { // 归一化结果为标准的-1/1,兼容自定义比较器返回非标准整数值的情况 return elementCompareResult < 0 ? -1 : 1; } } }
可调整的细节
- 如果业务要求输入序列必须非空,可以删除开头的空引用判断,改为抛出
ArgumentNullException做参数校验 - 不需要将序列转换为数组/List,原生支持懒加载序列(比如LINQ查询结果、大文件逐行读取的流序列等),内存效率更高
内容的提问来源于stack exchange,提问作者RRuseva
相关产品推荐
相关产品推荐

