UnionBin Linq实施 [英] UnionBy Linq Implementation

查看:32
本文介绍了UnionBin Linq实施的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Union上实现一个比较对象属性(而不是对象本身)的实现.我提出了以下建议:

public static IEnumerable<TSource> UnionBy<TSource, TKey>(
    this IEnumerable<TSource> first,
    IEnumerable<TSource> second,
    Func<TSource, TKey> keySelector,
    IEqualityComparer<TKey> keyComparer = null)
{
    HashSet<TKey> keys = new HashSet<TKey>(keyComparer);
    foreach (TSource element in first)
    {
        if (keys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
    foreach (TSource element in second)
    {
        if (!keys.Add(keySelector(element)))
        {
            continue;
        }
        yield return element;
    }
}

我可以这样说:

result = first.UnionBy(second, x => x.Property1);

这对我有用,但是我想知道Linq中是否还没有实现我缺少的东西(除了实现我自己的EqualityComparer 外,对我来说似乎不太直观).

因为我每次想要这个联合时都不会使用相同的属性,所以我要么必须为每种情况创建多个EqualityComparer,但这对我来说似乎不正确,或者是制作一些通用的EqualityComparer这将包含一个属性选择器Func.对我来说,似乎不像提供一个接受属性选择器本身的通用Linq扩展那样直观.

解决方案

是的,您可以按如下所示编写它:

var q = first.Concat(second).GroupBy(x => x.Property1).Select(x => x.First());

I needed an implementation on Union that compares a property of an object, rather the objects themselves. I came up with the following:

public static IEnumerable<TSource> UnionBy<TSource, TKey>(
    this IEnumerable<TSource> first,
    IEnumerable<TSource> second,
    Func<TSource, TKey> keySelector,
    IEqualityComparer<TKey> keyComparer = null)
{
    HashSet<TKey> keys = new HashSet<TKey>(keyComparer);
    foreach (TSource element in first)
    {
        if (keys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
    foreach (TSource element in second)
    {
        if (!keys.Add(keySelector(element)))
        {
            continue;
        }
        yield return element;
    }
}

which I can use by saying something along the lines of:

result = first.UnionBy(second, x => x.Property1);

Which works for me, but I was wondering if there wasn't something already implemented in Linq that I was missing (other than implementing my own EqualityComparer which to me seems less intuitive).

Since I won't be using the same properties every time I want this union I would either have to make multiple EqualityComparer's for each situation which doesn't seem correct to me, or make some generic EqualityComparer that would take in a property selector Func. It seemed less intuitive to me than just providing a generic Linq extension that accepted the property selector itself.

解决方案

Yes you can write it as follows instead:

var q = first.Concat(second).GroupBy(x => x.Property1).Select(x => x.First());

这篇关于UnionBin Linq实施的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆