简体   繁体   English

使用linq从列表中的2个可能字段中选择distinct int

[英]Select distinct int from 2 possible fields in list using linq

I've looked for a solution but I can't quite figure it. 我找了一个解决方案,但我无法理解它。 It strikes me that linq should be able to handle this neatly but I'm not the best at formulating linq queries. 令我感到震惊的是linq应该能够整齐地处理这个问题,但我并不是最好的制定linq查询。 Basically I have a class; 基本上我有一堂课;

public class Message
{
    public int CreatedByPersonID { get; set; }
    public int? PostedToPersonID { get; set; }
}

What I'm looking for is the linq equivilant of; 我正在寻找的是linq等效的;

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);
    }
}

Is there a linq version of this? 有linq版本吗? Or am I expecting too much of the technology...? 或者我期待太多的技术......? I know I'm looking for some version of Select() but I don't know how to formulate a distinct with multiple fields 我知道我正在寻找一些版本的Select()但我不知道如何用多个字段来表达一个distinct

List<int> personIDs = 
     messages.SelectMany(m => m.PostedToPersonID.HasValue ?
                  new int[] { m.PostedToPersonID.Value, m.CreatedByPersonID } :
                  new int[] { m.CreatedByPersonID })
             .Distinct()
             .ToList();

Another option is enumerating twice: 另一种选择是枚举两次:

List<int> personIDs =
    messages.Where(m => m.PostedToPersonID.HasValue)
            .Select(m => m.PostedToPersonID.Value)
            .Concat(messages.Select(m => m.CreatedByPersonID))
            .Distinct()
            .ToList();

But possibly without Linq you have more readable and faster code 但是,如果没有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;
     }
}

One more solution - single enumerating with distinct values 还有一个解决方案 - 单个枚举具有不同的值

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM