如何使用LINQ合并对象列表

huangapple go评论51阅读模式
英文:

How to merge a list of objects using LINQ

问题

我有一个定义如下的类

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;
}
英文:

I have a class defined below

public class ResultClass()
{
    public HashSet&lt;string&gt; VerifiedResults { get;  private set; }
    public HashSet&lt;string&gt; UnverifiedResults { get;  private set; }
    bool IsBlocked {get; private set; }
}

If I have a list containing items for ResultClass, for eg., List&lt;ResultClass&gt;() , how can I combine the results into a single ResultClass object using LINQ.

Is a way to do what my code below does, but with LINQ, instead?

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

答案1

得分: 2

这可以通过使用LINQ的Aggregate函数来实现,如下面的示例所示:

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实例中,既在“已验证”属性中又在“未验证”属性中可能发生冲突。可能需要调整累加器lambda表达式以获得您想要的结果。
英文:

This can be achieved using the LINQ Aggregate function, as can be seen in following example:

public class ResultClass
{
   public HashSet&lt;string&gt; VerifiedResults { get; set; } = new();
   public HashSet&lt;string&gt; 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) =&gt;
      {
         r.IsBlocked = r.IsBlocked || next.IsBlocked;
         r.VerifiedResults.UnionWith(next.VerifiedResults);
         r.UnverifiedResults.UnionWith(next.UnverifiedResults);
         return r;        
       });
}

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

}

A few remarks:

  • I adapted your ResultClass to remove compiler errors and to make it possible to initialize a list of them easily.

  • for the &#39;IsBlocked property, I used the logical OR of all the individual IsBlocked properties.

  • You should use UnionWith rather than Union in this case.

  • It might be a good idea to think about possible conflicts where the same string occurs in different ResultClass instances, both in 'verified' and 'unverified' properties. It may be necessary to adapt the accumulator lambda expression to get the results you want.

答案2

得分: 1

如@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的评论。

英文:

As @iSR5 mentioned, you can use SelectMany. I am not sure how do you plan to assign the IsBlocked, but this seems to behave like your code:

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

Also, please read @Johan Donne comments.

huangapple
  • 本文由 发表于 2023年2月19日 11:36:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定