【问题标题】:C# LINQ - how to DistinctBy two properties but preserve all properties in the classC# LINQ - 如何区分两个属性但保留类中的所有属性
【发布时间】:2014-09-07 13:16:02
【问题描述】:

我有一个类集合,集合中的每个类都有三个属性,但需要通过类集合上的两个属性来区分。令人困惑的部分是,在我只区分了两个属性之后,我需要所有三个属性。最明显的例子说使用您想要区分的属性创建一个匿名类型,但这会摆脱我需要在不同操作之后位于项目集合中的第三个属性。我如何区分三个属性中的两个,但最终结果是包含所有三个属性的类的集合?班级是:

public class Foo
{
public int PropertyOne {get; set;}
public int PropertyTwo {get; set;}
public string PropertyThree {get; set;}
}

// fake example of what I want but
// final result has all three properties in the collection still
var finalResult = allItems.DistinctBy(i => i.PropertyOne, i.PropertyTwo).ToArray();

感谢您的帮助!

【问题讨论】:

  • 你真的尝试过创建匿名类型吗?它仅用作分组的键......您的 src 中的项目不会使用 lambda 投影到输出序列中,它们会保持不变。试试看。
  • 为什么不创建IEqualityComparer并使用LINQ的Distict方法?
  • @zaf:创建IEqualityComparer 似乎需要很多开销,因为可以像source.GroupBy(keySelector).Select(g => g.First()) 一样简单地表述

标签: c# collections distinct


【解决方案1】:

如果你看implementation of .DistinctBy

    private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
    {
#if !NO_HASHSET
        var knownKeys = new HashSet<TKey>(comparer);
        foreach (var element in source)
        {
            if (knownKeys.Add(keySelector(element)))
            {
                yield return element;
            }
        }
#else
        //
        // On platforms where LINQ is available but no HashSet<T>
        // (like on Silverlight), implement this operator using
        // existing LINQ operators. Using GroupBy is slightly less
        // efficient since it has do all the grouping work before
        // it can start to yield any one element from the source.
        //

        return source.GroupBy(keySelector, comparer).Select(g => g.First());
#endif
    }

如果您查看!NO_HASHSET 实现...请注意源中的元素是如何产生不变的...

就我个人而言,我会完全避免使用 morelinq 来解决这个问题,而直接使用第二个实现:

allItems.GroupBy(i => new{i.PropertyOne, i.PropertyTwo}).Select(g => g.First())

【讨论】:

  • 感谢大家的回复。我接受了分组建议 - 我没有意识到在分组操作之后仍然会包含第三个属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多