[英]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.