合并IEnumerable中的重复元素

时间:2013-09-09 10:55:05

标签: c# .net linq

我目前有一个IEnumerable<MyObject>,其中MyObject的属性为String Namelong Value

如果我要在Enumerable中有10个MyObject个实例,每个实例都有不同的名称和值,除了一个与另一个具有相同名称的实例。

.NET(或LINQ)是否有内置方法允许我查找副本,如果可能的话,合并Value属性,以便最终只有9个元素在枚举中,每个具有不同的Name且具有重复的Value具有等于其自身和副本之和的IEnumerable

到目前为止,我发现迭代整个IEnumerable的唯一方法是查找重复项并生成新的{{1}}个唯一项目,但这似乎不整齐而且速度慢。

4 个答案:

答案 0 :(得分:17)

您可以按名称和项目结果将项目分组为“合并”对象:

objects.GroupBy(o => o.Name)
       .Select(g => new MyObject { Name = g.Key, Value = g.Sum(o => o.Value) });

更新:另一个选项,如果不希望新的MyObject实例化(例如,你在这个类中有很多属性,或者你应该保留引用),那么你可以使用聚合作为累加器组中的第一项:

objects.GroupBy(o => o.Name)
       .Select(g => g.Skip(1).Aggregate(
                        g.First(), (a, o) => { a.Value += o.Value; return a; }));

答案 1 :(得分:7)

list.GroupBy(e => e.Name).Select(group => new MyObject
    {
        Name = group.Key,
        Value = group.Sum(e => e.Value)
    }
)

<强>更新
另一种变体:

list.GroupBy(
    e => e.Name,
    e => e,
    (name, group) => group.Aggregate((result, e) =>
        {
            result.Value += e.Value;
            return result;
        }
    )
)

答案 2 :(得分:3)

我不知道单一的方法解决方案,但是:

set.GroupBy(g=>g.Name).Select(g=> new MyObject{Name=g.Key, Value=g.Sum(i=>i.Value)});

答案 3 :(得分:1)

实现IEquatable接口并使用Ditinct方法。如下:

internal class Program
{
    private static void Main(string[] args)
    {
        var items = new List<MyClass>
                    {
                        new MyClass
                        {
                            Name = "Name1",
                            Value = 50
                        },
                        new MyClass
                        {
                            Name = "Name2",
                            Value = 20
                        },
                        new MyClass
                        {
                            Name = "Name3",
                            Value = 50
                        }
                    };
        var distinct = items.Distinct().ToList();
    }
}

internal class MyClass : **IEquatable<MyClass>**
{
    public String Name { get; set; }
    public int Value { get; set; }

    **public bool Equals(MyClass other)
    {
        if (ReferenceEquals(null, other))
            return false;
        if (ReferenceEquals(this, other))
            return true;
        return this.Value == other.Value;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        if (ReferenceEquals(this, obj))
            return true;
        if (obj.GetType() != this.GetType())
            return false;
        return this.Equals((MyClass)obj);
    }

    public override int GetHashCode()
    {
        return this.Value;
    }

    public static bool operator ==(MyClass left, MyClass right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(MyClass left, MyClass right)
    {
        return !Equals(left, right);
    }**
}
相关问题