我有以下两个来自两个不同仓库的清单。

var list1 = new List<Tshirt> {
    new Tshirt(){ Color = "blue", size="M", qty=3 },
    new Tshirt(){ Color = "red", size="M", qty=2 },
    new Tshirt(){ Color = "green", size="M", qty=3 },
    new Tshirt(){ Color = "blue", size="M", qty=3 },
}

var list2 = new List<Tshirt> {
    new Tshirt(){ Color = "blue", size="M", qty=5 },
    new Tshirt(){ Color = "red", size="M", qty=7 },
}


使用LINQ,如何最终得到这样的组合列表。

var list3 = new List<Tshirt> {
    new Tshirt(){ Color = "blue", size="M", qty=11 },
    new Tshirt(){ Color = "red", size="M", qty=9 },
    new Tshirt(){ Color = "green", size="M", qty=3 }
}

最佳答案

(我最初错误地回答了这个问题,请参见下面的第二个标题(“将所有不同的Tshirt实例结合在一起”)作为我原来无关的答案)

合并所有Tshirt实例并汇总其数量:

我看到您使用的是color + size元组来唯一标识T恤的类型,这意味着,如果我们将所有Tshirt实例(Concat)组合在一起,然后按color + size,然后按 Sum值,然后在新列表中返回新的qty实例。

List<Tshirt> aggregatedShirts = uniqueShirts = Enumerable
    .Empty<Tshirt>()
    .Concat( list1 )
    .Concat( list2 )
    .GroupBy( shirt => new { shirt.Color, shirt.size } )
    .Select( grp => new Tshirt()
    {
        Color = grp.Key.Color,
        size  = grp.Key.size,
        qty   = grp.Sum( shirt => shirt.qty )
    } )
    .ToList();


将所有不同的Tshirt实例组合在一起

假设Tshirt实现了class Tshirt,则只需使用IEquatable<Tshirt>

我会这样做,其他人可能不想使用Concat( ... ).Distinct().ToList()

List<Tshirt> uniqueShirts = Enumerable
    .Empty<Tshirt>()
    .Concat( list1 )
    .Concat( list2 )
    .Distinct()
    .ToList();


如果Empty不实现Tshirt,则可以使用接受IEquatableDistinct重载:

class TshirtComparer : IEqualityComparer<Tshirt>
{
    public static TshirtComparer Instance { get; } = new TshirtComparer();

    public Boolean Equals(Tshirt x, Tshirt y)
    {
        if( ( x == null ) != ( y == null ) ) return false;
        if( x == null ) return true;

        return x.Color == y.Color && x.size == y.size && x.qty == y.qty;
    }

    public Int32 GetHashCode(Tshirt value)
    {
        if( value == null ) return 0;
        // See https://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode
        Int32 hash = 17;
        hash = hash * 23 + value.Color?.GetHashCode() ?? 0;
        hash = hash * 23 + value.size?.GetHashCode() ?? 0;
        hash = hash * 23 + value.qty;
        return hash;
    }
}


用法:

List<Tshirt> uniqueShirts = Enumerable
    .Empty<Tshirt>()
    .Concat( list1 )
    .Concat( list2 )
    .Distinct( TshirtComparer.Instance )
    .ToList();


然后得到总量:

Int32 totalQuantity = uniqueShirts.Sum( shirt => shirt.qty );

关于c# - 使用Linq合并两个列表并获得总量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53454968/

10-11 14:57