UnionBy Linq的实现[英] UnionBy Linq Implementation

本文是小编为大家收集整理的关于UnionBy Linq的实现的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我需要在 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());

本文地址:https://www.itbaoku.cn/post/1556845.html

问题描述

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());
相关标签/搜索