C#中如何使用LINQ从列表数据中获取唯一不重复的名称
C# LINQ 按ID分组提取唯一名称实现
场景规则
数据源为实体集合,存在两类数据特征:
- 部分ID关联的多条记录,
Name字段值完全一致 - 剩余ID关联的多条记录,
Name字段值互不相同
需要通过LINQ查询,按ID维度返回唯一的名称结果:同ID下名称全重复时返回该名称,同ID下存在多个不同名称时按指定规则返回结果。
实现步骤
1. 定义实体与测试数据
// 业务实体示例 public class DataItem { public int Id { get; set; } public string Name { get; set; } } // 测试数据源 var testData = new List<DataItem> { new() { Id = 1, Name = "Apple" }, new() { Id = 1, Name = "Apple" }, new() { Id = 2, Name = "Banana" }, new() { Id = 2, Name = "Orange" }, new() { Id = 3, Name = "Grape" }, new() { Id = 3, Name = "Grape" } };
2. 基础实现(小数据量场景)
按ID分组后,对组内名称去重判断,根据结果返回对应值:
var queryResult = testData .GroupBy(item => item.Id) .Select(group => { var distinctNames = group.Select(item => item.Name).Distinct().ToList(); return new { Id = group.Key, // 全重名返回唯一名称,存在多名时默认取组内第一条记录的名称,可按需替换规则 Name = distinctNames.Count == 1 ? distinctNames[0] : group.First().Name }; }) .ToList();
3. 优化实现(大数据量场景)
单ID关联记录量较大时,不需要遍历全部分组记录判断重名,最多取2个不同值即可判定是否存在多名称,减少遍历开销:
var optimizedResult = testData .GroupBy(item => item.Id) .Select(group => { // 取到2个不同名称就停止遍历,避免无意义的全量扫描 var nameEnum = group.Select(item => item.Name).Distinct().Take(2).GetEnumerator(); nameEnum.MoveNext(); string firstDistinctName = nameEnum.Current; bool isAllNameSame = !nameEnum.MoveNext(); return new { Id = group.Key, Name = isAllNameSame ? firstDistinctName // 多名称场景可自定义取值逻辑,比如按名称排序、按时间取最新等 : group.OrderBy(item => item.Name).First().Name }; }) .ToList();
扩展提示:如果需要区分「同ID全重名」和「同ID多名」的场景,可以在返回结果中增加标识字段,或者将多名称场景的返回值替换为自定义提示,方便后续数据校验。
内容的提问来源于stack exchange,提问作者user1587381
相关产品推荐
相关产品推荐

