在C#中使用linq合并对象列表

zfycwa2u  于 2023-02-20  发布在  C#
关注(0)|答案(2)|浏览(290)

我有一个如下定义的类

public class ResultClass()
{
    public HashSet<string> VerifiedResults { get;  private set; }
    public HashSet<string> UnverifiedResults { get;  private set; }
    bool IsBlocked {get; private set; }
}

如果我有一个包含ResultClass项的列表,例如List<ResultClass>(),我如何使用linq将结果合并到一个ResultClass对象中。基本上,我想知道是否有更好的方法使用linq完成以下操作。

var finalResult = new ResultClass();
foreach(var item in listOfResultClass)
{
    finalResult.VerifiedResults.Union(item.VerifiedResults);
    finalResult.UnverifiedResults.Union(item.UnverifiedResults);
    finalResult.IsBlocked = item.IsBlocked;
}
xzv2uavs

xzv2uavs1#

这可以使用LINQ Aggregate function实现,如以下示例所示:

public class ResultClass
{
   public HashSet<string> VerifiedResults { get; set; } = new();
   public HashSet<string> UnverifiedResults { get; set; } = new();
   public bool IsBlocked { get; set; } = false;
}

internal class Program
{
   private static void Main()
   {
      var results = GetResults();

      var finalResult = results.Aggregate(new ResultClass(), (r, next) =>
      {
         r.IsBlocked = r.IsBlocked || next.IsBlocked;
         r.VerifiedResults.UnionWith(next.VerifiedResults);
         r.UnverifiedResults.UnionWith(next.UnverifiedResults);
         return r;        
       });
}

private static List<ResultClass> GetResults()
{
    return new List<ResultClass>()
    {
      new ResultClass()
      {
         VerifiedResults = new HashSet<string>{"first", "second" },
         UnverifiedResults = new HashSet<string>{"third" },
         IsBlocked = false
      },
      new ResultClass()
      {
         VerifiedResults = new HashSet<string>{"first", "fourth" },
         UnverifiedResults = new HashSet<string>{"fifth" },
         IsBlocked = true
      },
      new ResultClass()
      {
         VerifiedResults = new HashSet<string> (),
         UnverifiedResults = new HashSet<string>{"sixt", "seventh" },
         IsBlocked = false
      }
    };
  }

}
几点意见:

  • 我修改了您的ResultClass,以消除编译器错误,并使其可以轻松地初始化它们的列表。
  • 对于'IsBlocked属性,我使用了所有单个IsBlocked属性的逻辑OR。
  • 在这种情况下,应该使用UnionWith而不是Union
  • 如果相同的字符串出现在不同的ResultClass示例中(“verified”和“unverified”属性中),考虑可能的冲突可能是个好主意。可能需要调整累加器lambda表达式以获得所需的结果。
7rtdyuoh

7rtdyuoh2#

正如@iSR5提到的,您可以使用SelectMany,我不确定您计划如何分配IsBlocked,但这似乎与您的代码的行为相同:

var result = new ResultClass()
{
    VerifiedResults = new HashSet<string>(results.SelectMany(x => x.VerifiedResults)),
    UnverifiedResults = new HashSet<string>(results.SelectMany(x => x.UnverifiedResults)),
    IsBlocked = results.LastOrDefault().IsBlocked,
};

另外,请阅读@Johan Donne的评论。

相关问题