簡體   English   中英

在 c# 中使用 linq 相交和相等將多個列表組合成一個單獨的列表

[英]Combining several lists into a single distinct list using linq intersect and equality in c#

我需要使用 linq 將多個列表合並為一個 combinedDistinct 列表並相交。 我最終得到一個空列表。 知道我可能做錯了什么嗎?

這是我的代碼:

// 合並所有不同的材料項

List<Material> combinedMaterialList = new List<Material>();

foreach (var project in projects)
{
     combinedMaterialList = combinedMaterialList.Intersect(project.Materials).ToList();
}

這是 Material class,因為 intersect 將基於 Equality 工作:

public int Id { get; set; }
public int ExternalId { get; set; }
public string? Name { get; set; }
public decimal Quantity { get; set; }

public bool Equals(Material m)
{
    if (m is null)
    {
        return false;
    }

    // Optimization for a common success case.
    if (Object.ReferenceEquals(this, m))
    {
        return true;
    }

    // If run-time types are not exactly the same, return false.
    if (this.GetType() != m.GetType())
    {
        return false;
    }

    // Return true if the fields match.
    // Note that the base class is not invoked because it is
    // System.Object, which defines Equals as reference equality.
    return (ExternalId == m.ExternalId);
}

    public override int GetHashCode()
    {
        return HashCode.Combine(Id, ExternalId, Name, Quantity);
    }

首先確保您已經為Material class 實現了EqualsGetHashCode

public class Material: IEquatable<Material> {
  ...
  
  public bool Equals(Material other) {
    if (ReferenceEquals(this, other))
      return true;
    if (other is null)
      return false;

    return ExternalId == other.ExternalId;
  }

  public override bool Equals(object o) => o is Material other && Equals(other);

  // Note, that GetHashCode must not be more restrictive than Equals:
  // If Equals compare ExternalId only, so must do GetHashCode
  public override int GetHashCode() => ExternalId; 
}

實施Equals后,您應該選擇以下方法之一:

  • Intersect兩個列表中的所有項目
  • Union至少在一個列表中的所有項目
  • Except :所有在第一個列表中但不在第二個列表中的項目

無論如何都會刪除重復項。

例如:

// Since combinedMaterialList is empty,
// Intersect or Except have no meaning here: the result will be 
// an empty list. The only reasonable choice is Union 
List<Material> combinedMaterialList = new List<Material>();

// Combined list contains item from all project.Materials,
// duplicates removed
foreach (var project in projects) {
  combinedMaterialList = combinedMaterialList
    .Union(project.Materials)
    .ToList();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM