0

我需要了解两个 IEnumerable 之间的差异。我为它写了扩展方法。但正如你所看到的,它有性能损失。谁能写出更好的版本?

编辑

在第一次回复后,我明白我无法很好地解释。我正在访问这两个阵列三次。这是性能损失。应该是单发。

PS:两者都是可选的:)

public static class LinqExtensions
{
 public static ComparisonResult<T> Compare<T>(this IEnumerable<T> source, IEnumerable<T> target)
    {
        // Looping three times is performance penalty!  
        var res = new ComparisonResult<T>
        {
            OnlySource = source.Except(target), 
            OnlyTarget = target.Except(source), 
            Both = source.Intersect(target)
        };
        return res;
    }
}

public class ComparisonResult<T>
{
    public IEnumerable<T> OnlySource { get; set; }
    public IEnumerable<T> OnlyTarget { get; set; }
    public IEnumerable<T> Both { get; set; }
}
4

2 回答 2

0

您正在寻找有效的完全外连接。

将所有项目插入到Dictionary<TKey, Tuple<TLeft, TRight>>. 如果给定的键不存在,则将其添加到字典中。如果存在,请更新该值。如果设置了“左成员”,这意味着该项目存在于左源集合中(您称它为source)。对的成员则相反。您可以在两个集合上使用单次传递来做到这一点。

之后,您遍历此字典的所有值并将相应的项目输出到三个集合之一,或者您只需将其作为 an 返回,IEnumerable<Tuple<TLeft, TRight>>从而节省对结果集合的需求。

于 2013-10-14T14:50:00.890 回答
0

取决于用例,这可能更有效:

 public static ComparisonResult<T> Compare<T>(this IEnumerable<T> source, IEnumerable<T> target)
    {
        var both = source.Intersect(target).ToArray();
        if (both.Any())
        {
            return new ComparisonResult<T>
            {
                OnlySource = source.Except(both),
                OnlyTarget = target.Except(both),
                Both = both
            };
        }
        else
        {
            return new ComparisonResult<T>
            {
                OnlySource = source,
                OnlyTarget = target,
                Both = both
            };
        }
    }
于 2013-10-11T14:24:30.180 回答