C# 使用linq的两个列表之间的差异

C# 使用linq的两个列表之间的差异,c#,linq,list,C#,Linq,List,我有两个列表和两个字段。我不知道哪一个更大 我想做到这一点: newList oldList Fruit Qty Diff Fruit Qty -------------------------------------------- apple 3 +1 apple 2 -2 pear 2 peach

我有两个列表和两个字段。我不知道哪一个更大

我想做到这一点:

        newList              oldList
Fruit       Qty     Diff    Fruit       Qty
--------------------------------------------
apple       3       +1      apple       2
                    -2      pear        2
peach       4       +3      peach       1
melon       5        0      melon       5
coconut     2       +2      
mango       4        0      mango       4
banana      2       -1      banana      3
lychi       1       +1      
                    -3      pineapple   3
在左边你可以看到新列表在右边旧列表。如果我将oldList与newList进行比较,我希望看到这两个列表之间的每一行以及数量上的差异

我写了这个,它会给我两个列表中都没有的水果(xor)


但我也不知道如何将它与数量结合起来。

我看不到LINQ有一种性能好、可读性好的方法。我更喜欢LINQ和循环的混合:

var oldGrouped = oldList.ToDictionary(x => x.Fruit, x => x.Qty);
var newGrouped = newList.ToDictionary(x => x.Fruit, x => x.Qty);

var result = new List<FruitSummary>();

foreach(var oldItem in oldGrouped)
{
    var summary = new FruitSummary { OldFruit = oldItem.Key, OldQty = oldItem.Value };
    if(newGrouped.TryGetValue(oldItem.Key, out int newQuantity) && newQuantity != 0)
    {
        summary.NewFruit = oldItem.Key;
        summary.NewQty = newQuantity;
    }
    summary.Diff = oldItem.Value - newQuantity;
    newGrouped.Remove(oldItem.Key);
    result.Add(summary);
}

foreach(var newItem in newGrouped)
{
    result.Add(new FruitSummary { Diff = -newItem.Value,
                                  NewFruit = newItem.Key,
                                  NewQty = newItem.Value });
}

我不认为LINQ有一种表现良好且可读性好的方法。我更喜欢LINQ和循环的混合:

var oldGrouped = oldList.ToDictionary(x => x.Fruit, x => x.Qty);
var newGrouped = newList.ToDictionary(x => x.Fruit, x => x.Qty);

var result = new List<FruitSummary>();

foreach(var oldItem in oldGrouped)
{
    var summary = new FruitSummary { OldFruit = oldItem.Key, OldQty = oldItem.Value };
    if(newGrouped.TryGetValue(oldItem.Key, out int newQuantity) && newQuantity != 0)
    {
        summary.NewFruit = oldItem.Key;
        summary.NewQty = newQuantity;
    }
    summary.Diff = oldItem.Value - newQuantity;
    newGrouped.Remove(oldItem.Key);
    result.Add(summary);
}

foreach(var newItem in newGrouped)
{
    result.Add(new FruitSummary { Diff = -newItem.Value,
                                  NewFruit = newItem.Key,
                                  NewQty = newItem.Value });
}

我假设您有一个
Fruit
类,如下所示:

public class FruitSummary
{
    public string OldFruit { get; set; }
    public string NewFruit { get; set; }
    public int OldQty { get; set; }
    public int NewQty { get; set; }
    public int Diff { get; set; }
}
public class Fruit
{
    public string Name {get; set;}
    public int Quantity {get; set;}
}
Console.WriteLine(string.Join(Environment.NewLine, result.Select(r => $"{r.Name} {r.Diff}")));
你有一个旧的和一个新的列表

List<Fruit> oldList = ...
List<Fruit> newList = ...
您可以这样输出结果:

public class FruitSummary
{
    public string OldFruit { get; set; }
    public string NewFruit { get; set; }
    public int OldQty { get; set; }
    public int NewQty { get; set; }
    public int Diff { get; set; }
}
public class Fruit
{
    public string Name {get; set;}
    public int Quantity {get; set;}
}
Console.WriteLine(string.Join(Environment.NewLine, result.Select(r => $"{r.Name} {r.Diff}")));


请注意,我之所以提出这个问题,是因为我喜欢linq“一行程序”,但使用
foreach
似乎比此查询更具可读性,甚至可能更快。

我假设您有一个
水果类,如下所示:

public class FruitSummary
{
    public string OldFruit { get; set; }
    public string NewFruit { get; set; }
    public int OldQty { get; set; }
    public int NewQty { get; set; }
    public int Diff { get; set; }
}
public class Fruit
{
    public string Name {get; set;}
    public int Quantity {get; set;}
}
Console.WriteLine(string.Join(Environment.NewLine, result.Select(r => $"{r.Name} {r.Diff}")));
你有一个旧的和一个新的列表

List<Fruit> oldList = ...
List<Fruit> newList = ...
您可以这样输出结果:

public class FruitSummary
{
    public string OldFruit { get; set; }
    public string NewFruit { get; set; }
    public int OldQty { get; set; }
    public int NewQty { get; set; }
    public int Diff { get; set; }
}
public class Fruit
{
    public string Name {get; set;}
    public int Quantity {get; set;}
}
Console.WriteLine(string.Join(Environment.NewLine, result.Select(r => $"{r.Name} {r.Diff}")));

请注意,我之所以这样做是因为我喜欢linq“一行程序”,但使用
foreach
似乎比这个查询更具可读性,甚至可能更快

var difference = newList
    .Concat(oldList.Select(x => new { x.Fruit, Qty = -x.Qty }))
    .GroupBy(x => x.Fruit)
    .Select(g => new {Fruit = g.Key, Qty = g.Sum(x => x.Qty) });
当我运行
foreach(差异中的vard)Console.WriteLine(d),我得到:

{ Fruit = apple, Qty = 1 }
{ Fruit = peach, Qty = 3 }
{ Fruit = melon, Qty = 0 }
{ Fruit = coconut, Qty = 2 }
{ Fruit = mango, Qty = 0 }
{ Fruit = banana, Qty = -1 }
{ Fruit = lychi, Qty = 1 }
{ Fruit = pear, Qty = -2 }
{ Fruit = pineapple, Qty = -3 }
像这样的

var difference = newList
    .Concat(oldList.Select(x => new { x.Fruit, Qty = -x.Qty }))
    .GroupBy(x => x.Fruit)
    .Select(g => new {Fruit = g.Key, Qty = g.Sum(x => x.Qty) });
当我运行
foreach(差异中的vard)Console.WriteLine(d),我得到:

{ Fruit = apple, Qty = 1 }
{ Fruit = peach, Qty = 3 }
{ Fruit = melon, Qty = 0 }
{ Fruit = coconut, Qty = 2 }
{ Fruit = mango, Qty = 0 }
{ Fruit = banana, Qty = -1 }
{ Fruit = lychi, Qty = 1 }
{ Fruit = pear, Qty = -2 }
{ Fruit = pineapple, Qty = -3 }

这似乎是使用普通的
foreach
然后在该循环中使用简单LINQ的一种方式。这些真的是清单吗?或者它们实际上是字典?你的
水果
是一门课吗?如果是这样,请将其添加到您的问题中。这些列表是来自数据库的linq查询的结果,其中我只取了两列,FROUT和Qty。所以水果是一个字段。这看起来像是在循环中使用普通的
foreach
然后使用简单的LINQ。这些真的是清单吗?或者它们实际上是字典?你的
水果
是一门课吗?如果是这样,请将其添加到您的问题中。这些列表是来自数据库的linq查询的结果,其中我只取了两列,FROUT和Qty。所以水果是一块田地。