簡體   English   中英

如何在C#中使用EqualityComparer返回Distinct中的特定項

[英]How to return a specific item in Distinct using EqualityComparer in C#

我已經定義了一個CustomListComparer ,用於比較List<int> AList<int> B ,如果兩個列表的Union至少等於列表,則認為它們相等。

var distinctLists = MyLists.Distinct(new CustomListComparer()).ToList();

public bool Equals(Frame other)
{
    var union = CustomList.Union(other.CustomList).ToList();
    return union.SequenceEqual(CustomList) ||
           union.SequenceEqual(other.CustomList);
}

例如,以下列表是相同的:

ListA = {1,2,3}
ListB = {1,2,3,4}

以下列表不是:

ListA = {1,5}
ListB = {1,2,3,4}

現在一切正常。 但這是我的問題:哪一個列表(A或B)進入distinctLists 我有什么發言權嗎? 或者這一切都由編譯器本身處理?

我的意思是說EqualityComparer認為兩個列表相等。 並將其中一個添加到distinctLists 它添加了哪一個? 我想要添加更多項目的列表。

Distinct總是添加它看到的第一個元素。 所以它取決於你傳入的序列的順序。

來源相當簡單,可以在這里找到

static IEnumerable<TSource> DistinctIterator<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer) {
    Set<TSource> set = new Set<TSource>(comparer);
    foreach (TSource element in source)
        if (set.Add(element)) yield return element;
}

如果您需要返回包含更多元素的列表,則需要自行滾動。 值得注意的是, Distinct是懶惰的,但你要求的實現需要急切的實現。

static class MyDistinctExtensions
{
    public static IEnumerable<T> DistinctMaxElements<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer) where T : ICollection
    {
        Dictionary<T, List<T>> dictionary = new Dictionary<T, List<T>>(comparer);
        foreach (var item in source)
        {
            List<T> list;
            if (!dictionary.TryGetValue(item, out list))
            {
                list = new List<T>();
                dictionary.Add(item, list);
            }
            list.Add(item);
        }

        foreach (var list in dictionary.Values)
        {
            yield return list.Select(x => new { List = x, Count = x.Count })
                .OrderByDescending(x => x.Count)
                .First().List;
        }
    }
}

使用天真的實現更新了答案,但未經過測試。

您可以將GroupByMaxBy方法一起使用而不是Distinct ::

var distinctLists = MyLists.GroupBy(x => x, new CustomListComparer())
                           .Select(g => g.MaxBy(x => x.Count))
                           .ToList();

這將使用比較器對列表進行分組,並選擇每個組中包含最大項目的列表。

MaxBy在這種情況下非常有用,您可以在MoreLINQ庫中找到它。

編輯:使用純LINQ:

var distinctLists = MyLists.GroupBy(x => x, new CustomListComparer())
                           .Select(g => g.First(x => x.Count == g.Max(l => l.Count)))
                           .ToList();

暫無
暫無

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

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