使用linq从列表中的两个可能字段中选择不同的int
本文关键字:字段 选择 int 两个 linq 列表 使用 | 更新日期: 2023-09-27 18:00:27
我一直在寻找解决方案,但我不太清楚。我突然想到linq应该能够巧妙地处理这一问题,但我并不擅长制定linq查询。基本上我有一节课;
public class Message
{
public int CreatedByPersonID { get; set; }
public int? PostedToPersonID { get; set; }
}
我要找的是对;
List<int> personIDs = new List<int>();
foreach (Message message in messages)
{
if (!personIDs.Contains(message.CreatedByPersonID))
{
personIDs.Add(message.CreatedByPersonID);
}
if (message.PostedToPersonID != null && !personIDs.Contains(message.PostedToPersonID.Value))
{
personIDs.Add(message.PostedToPersonID.Value);
}
}
这个有linq版本吗?还是我对技术期望过高。。。?我知道我正在寻找某种版本的Select()
,但我不知道如何用多个字段来表示distinct
List<int> personIDs =
messages.SelectMany(m => m.PostedToPersonID.HasValue ?
new int[] { m.PostedToPersonID.Value, m.CreatedByPersonID } :
new int[] { m.CreatedByPersonID })
.Distinct()
.ToList();
另一种选择是枚举两次:
List<int> personIDs =
messages.Where(m => m.PostedToPersonID.HasValue)
.Select(m => m.PostedToPersonID.Value)
.Concat(messages.Select(m => m.CreatedByPersonID))
.Distinct()
.ToList();
但如果没有Linq,你可能会有更可读、更快的代码
public IEnumerable<int> GetAllPersonIdsFrom(IEnumerable<Message> messages)
{
foreach(var message in messages)
{
yield return message.CreatedByPersonID;
if (message.PostedToPersonID.HasValue)
yield return message.PostedToPersonID.Value;
}
}
另一个解决方案-具有不同值的单一枚举
public static List<int> GetDistinctPersonIdsFrom(IEnumerable<Message> messages)
{
HashSet<int> ids = new HashSet<int>();
foreach (var message in messages)
{
ids.Add(message.CreatedByPersonID);
if (message.PostedToPersonID.HasValue)
ids.Add(message.PostedToPersonID.Value);
}
return ids.ToList();
}