如何用单条LINQ语句实现两整数列表按末尾数字配对并排序?
问题
给定两个元素互不重复的正整数序列integerList1和integerList2,需要获取满足以下条件的NumberPair集合:
- 配对第一个元素来自
integerList1,第二个来自integerList2; - 两个元素末尾数字相同;
NumberPair包含Item1和Item2字段;- 结果需按
Item1升序排序,Item1相同时按Item2升序排序。
示例
输入:
integerList1: new[] { 1, 12, 4, 5, 78 } integerList2: new[] { 1, 42, 75, 65, 8, 97 }
预期结果:
new[] { new NumberPair{Item1 = 1, Item2 = 1}, new NumberPair{Item1 = 5, Item2 = 65}, new NumberPair{Item1 = 5, Item2 = 75}, new NumberPair{Item1 = 12, Item2 = 42}, new NumberPair{Item1 = 78, Item2 = 8} }
现有尝试代码
用户原本的实现代码(非单条LINQ查询):
var lastDigitsGroups1 = integerList1.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList()); var lastDigitsGroups2 = integerList2.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList()); var intersection = lastDigitsGroups1.Keys.Intersect(lastDigitsGroups2.Keys); foreach (var item in intersection) { var np = new NumberPair { Item1 = lastDigitsGroups1[item].FirstOrDefault(), Item2 = lastDigitsGroups2[item].FirstOrDefault() }; yield return np; }
单条LINQ查询解决方案
基础实现(简洁直观)
通过笛卡尔积筛选+排序,直接完成所有要求:
var result = integerList1 .SelectMany(num1 => integerList2 .Where(num2 => num1 % 10 == num2 % 10) .Select(num2 => new NumberPair { Item1 = num1, Item2 = num2 })) .OrderBy(np => np.Item1) .ThenBy(np => np.Item2) .ToList();
代码说明
SelectMany生成两个列表的笛卡尔积,同时筛选出末尾数字相同的配对;- 每个符合条件的配对直接实例化为
NumberPair对象; - 最后通过
OrderBy+ThenBy完成排序规则。
性能优化版(大数据量场景)
如果数据量较大,可通过分组关联减少无效遍历:
var result = integerList1.GroupBy(num => num % 10) .Join( integerList2.GroupBy(num => num % 10), g1 => g1.Key, g2 => g2.Key, (g1, g2) => g1.SelectMany(num1 => g2.Select(num2 => new NumberPair { Item1 = num1, Item2 = num2 }))) .SelectMany(np => np) .OrderBy(np => np.Item1) .ThenBy(np => np.Item2) .ToList();
优化说明
- 先分别对两个列表按末尾数字分组;
- 通过
Join关联拥有相同末尾数字的分组; - 对每组内的元素生成所有配对并展平结果;
- 最后执行排序,避免全量笛卡尔积的性能损耗。
内容的提问来源于stack exchange,提问作者Fatality99
相关产品推荐
相关产品推荐

