为了账号安全,请及时绑定邮箱和手机立即绑定

与兰达不同?

与兰达不同?

C#
哔哔one 2019-06-25 16:11:26
与兰达不同?是的,所以我有一个可枚举的,并希望从中得到不同的值。使用System.Linq,当然有一个扩展方法叫做Distinct..在简单的情况下,可以在没有参数的情况下使用它,例如:var distinctValues = myStringList.Distinct();好的,但是如果我有一个需要指定相等的对象的枚举,那么唯一可用的重载是:var distinctValues = myCustomerList.Distinct(someEqualityComparer);相等比较器参数必须是IEqualityComparer<T>..当然,我可以这样做,但它有点冗长,而且,嗯,是排他性的。我所期望的是一个过载,它需要一个羔羊,比如Func<T,bool>:var distinctValues    = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);有人知道是否存在这样的扩展,或者某种类似的解决方法?还是我遗漏了什么?或者,是否有一种方法可以指定IEQuityComper内联(妨碍我)?更新我发现Anders Hejlsberg对岗在MSDN论坛上讨论这个问题。他说:您将遇到的问题是,当两个对象比较相等时,它们必须具有相同的GetHashCode返回值(否则,DISTION内部使用的哈希表将不能正常工作)。我们使用IEQuityComper,因为它将Eques和GetHashCode的兼容实现打包到一个接口中。我想这是有道理的.。
查看完整描述

3 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

IEnumerable<Customer> filteredList = originalList  .GroupBy(customer => customer.CustomerId)
  .Select(group => group.First());


查看完整回答
反对 回复 2019-06-25
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

在我看来你想DistinctBy从…MoreLINQ..然后你可以写:

var distinctValues = myCustomerList.DistinctBy(c => c.CustomerId);

下面是一个缩减版本的DistinctBy(没有无效检查,也没有选择指定自己的钥匙比较者):

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
     (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector){
    HashSet<TKey> knownKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }}


查看完整回答
反对 回复 2019-06-25
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

把事情包扎起来..我想大多数像我一样来这里的人最简单解可能不使用任何库尽最大可能性能.

(我认为按方法接受的组在表现上是过分的。)

下面是使用质量检验员接口,它也适用于空值。

用法:

var filtered = taskList.DistinctBy(t => t.TaskExternalId).ToArray();

扩展方法码

public static class LinqExtensions{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
    {
        GeneralPropertyComparer<T, TKey> comparer = new GeneralPropertyComparer<T,TKey>(property);
        return items.Distinct(comparer);
    }   }public class GeneralPropertyComparer<T,TKey> : IEqualityComparer<T>{
    private Func<T, TKey> expr { get; set; }
    public GeneralPropertyComparer (Func<T, TKey> expr)
    {
        this.expr = expr;
    }
    public bool Equals(T left, T right)
    {
        var leftProp = expr.Invoke(left);
        var rightProp = expr.Invoke(right);
        if (leftProp == null && rightProp == null)
            return true;
        else if (leftProp == null ^ rightProp == null)
            return false;
        else
            return leftProp.Equals(rightProp);
    }
    public int GetHashCode(T obj)
    {
        var prop = expr.Invoke(obj);
        return (prop==null)? 0:prop.GetHashCode();
    }}


查看完整回答
反对 回复 2019-06-25
  • 3 回答
  • 0 关注
  • 454 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信