【问题标题】:How to remove (via linq) duplicates from a List of objects如何从对象列表中删除(通过 linq)重复项
【发布时间】:2026-02-11 02:00:02
【问题描述】:

我的主要对象,有一个属性是标签列表

    [SharedCosmosCollection("shared")]
    public class GlobalPageTemplate : ISharedCosmosEntity
    {
        /// <summary>
        /// Id
        /// </summary>
        [JsonProperty("Id")]
        public string Id { get; set; }

        /// <summary>
        /// Cosmos Entity name
        /// </summary>
        [CosmosPartitionKey]
        public string CosmosEntityName { get; set; }

        /// <summary>
        /// Page name
        /// </summary>
        public string ExtractedPageName { get; set; }

        /// <summary>
        /// Site collection Template Name
        /// </summary>
        public string ExtractedSitecollectionTemplateName { get; set; }

        /// <summary>
        /// GlobalDesignTenantId
        /// </summary>
        public string ExtractedGlobalDesignTenantId { get; set; }

        /// <summary>
        /// Global design tenant site collection url
        /// </summary>
        public string ExtractedGlobalDesigntenantSiteCollectionUrl { get; set; }


        /// <summary>
        /// Page template picture Url
        /// </summary>
        public string PageTemplatePictureUrl { get; set; }

        /// <summary>
        /// Base64 image of the page template
        /// </summary>
        public string Base64Image { get; set; }

        /// <summary>
        /// Name of the template
        /// </summary>
        public string PageTemplateName { get; set; }


        /// <summary>
        /// Page sections
        /// </summary>
        public List<Section> Sections { get; set; }

        /// <summary>
        /// Tags
        /// </summary>
        public List<Tag> Tags { get; set; }
    }

标签对象在这里:

 public class Tag : ISharedCosmosEntity
    {
        /// <summary>
        /// Id
        /// </summary>
        [JsonProperty("Id")]
        public string Id { get; set; }
        /// <summary>
        /// Tag name
        /// </summary>
        public string TagName { get; set; }
        /// <summary>
        /// cosmos entity name
        /// </summary>
        [CosmosPartitionKey]
        public string CosmosEntityName { get; set; }
    }

在我的 WebAPI 中,从前端,我可能会得到重复的标签,

如何在保存之前删除它们并留下一个干净的标签列表?

【问题讨论】:

标签: c# asp.net .net linq


【解决方案1】:

不完全是您问题的答案(其他答案都是有效的解决方案),但如果出于某种原因您希望实际提取重复的对象,例如调试、错误处理等,我想要提供以下内容。

var duplicates = someList
  .GroupBy(r => r.Id)
  .Where(g => g.Count() > 1)
  .ToList();

那么你有一种稍微不同的方式来管理你的列表,而不是纯粹的不同

someList = someList.Except(duplicates).ToList();

然后是没有重复的键的列表。

【讨论】:

    【解决方案2】:

    仅使用 linq 你可以这样做:

    如果标签具有唯一 ID:

    tags.GroupBy(x => x.Id).Select(x => x.First()).ToList();
    

    如果需要比较所有列:

    tags.GroupBy(x => new {x.Id, x.TagName, x.CosmosEntityName}).Select(x => x.First()).ToList();
    

    【讨论】:

      【解决方案3】:

      我可以建议将存储标签的数据结构更改为HashSet 吗?如果是这样,您可以执行this 之类的操作。

      HashSet 是唯一元素的无序集合。当我们想要防止重复的元素被放置在一个集合中时,通常会使用它。与列表相比,HashSet 的性能要好得多。

      基本上,您在初始化时为您的 HashSet 提供一个自定义 IEqualityComparer。

      public class TagComparer : IEqualityComparer<Tag>
      {
          public bool Equals(Tag x, Tag y)
          {
              return x.Id.Equals(y.Id, StringComparison.InvariantCultureIgnoreCase);
          }
      
          public int GetHashCode(Tag obj)
          {
              return obj.Id.GetHashCode();
          }
      }
      

      然后你就可以了

      HashSet<Tag> Tags = new HashSet<Tag>(new TagComparer());
      

      一般来说,我总是尝试使用对手头的问题有意义的数据结构。如果你知道你总是希望这个集合有独特的元素,那么我建议你使用 HashSet。

      如果你不能使用 HashSet 并且你想坚持使用列表,你可以在你的标签列表上使用 linq 的 Distinct 方法并从上面传入 TagComparer 对象。

      List<Tag> DistinctTagList = Tags.Distict(new TagComparer())
      

      【讨论】:

      • 哈希列表和字符串列表有什么区别?
      • 当然,HashSet 是一个无序集合或唯一元素。我会用描述更新我的答案
      【解决方案4】:

      您正在寻找的可能是 distict 方法: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.distinct?view=netframework-4.8

      为此,您还需要编写一个 IEqualityComparer,它可以通过属性 https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iequalitycomparer-1?view=netframework-4.8 进行简单比较

      然后你可以在你的 Enumerable 上调用它:

      var distinctTags = Tags.Distict(new TagEqualityComparer)
      

      还有equalComparer:

      class TagEqualityComparer : IEqualityComparer<Tag>
      {
          public bool Equals(Tag t1, Tag t2)
          {
              if (t2 == null && t1 == null)
                 return true;
              else if (t1 == null || t2 == null)
                 return false;
              else if(t1.Id == t2.Id)
                  return true;
              else
                  return false;
          }
      
          public int GetHashCode(Tag t)
          {
              // any custom hashingfunction here
          }
      }
      

      【讨论】: