簡體   English   中英

如何從對象列表中刪除(通過 linq)重復項

[英]How to remove (via linq) duplicates from a List of objects

我的主要對象有一個屬性,它是一個標簽列表

    [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 中,從前端,我可能會得到重復的標簽,

如何在保存之前刪除它們並留下干凈的標簽列表?

我可以建議將存儲標簽的數據結構更改為HashSet嗎? 如果是這樣,你就可以做一些像這樣

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

您正在尋找的可能是 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)

和equalityComparer:

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

使用 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();

不完全是您問題的答案(其他答案都是針對該問題的有效解決方案),但是如果出於某種原因您希望實際提取重復的對象,例如用於調試、錯誤處理等,我想提供以下。

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

然后你有一種稍微不同的方式來管理你的列表從純粹的不同

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

這是一個沒有重復的鍵列表。

暫無
暫無

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

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