【问题标题】:Use LINQ to populate a single list from two other lists without duplicates使用 LINQ 从其他两个列表中填充单个列表而不会重复
【发布时间】:2012-09-21 08:01:41
【问题描述】:

我有 2 个列表:-

OrigFruitList.Add(new Fruit { Category = "Apple", SubCategory = "" });
        OrigFruitList.Add(new Fruit { Category = "Apple", SubCategory = "Red Apple" });
        OrigFruitList.Add(new Fruit { Category = "Apple", SubCategory = "Green Apple" });
        OrigFruitList.Add(new Fruit { Category = "Orange", SubCategory = "" });
        OrigFruitList.Add(new Fruit { Category = "Peach", SubCategory = "" });
        OrigFruitList.Add(new Fruit { Category = "Grapes", SubCategory = "Green Grapes" });
        OrigFruitList.Add(new Fruit { Category = "Grapes", SubCategory = "Black Grapes" });
        OrigFruitList.Add(new Fruit { Category = "Bananas", SubCategory = "" });

        NormalFruitList.Add(new Fruit { Category = "Apple", SubCategory = "" });
        NormalFruitList.Add(new Fruit { Category = "Apple", SubCategory = "Red Apple" });
        NormalFruitList.Add(new Fruit { Category = "Apple", SubCategory = "Green Apple" });
        NormalFruitList.Add(new Fruit { Category = "Orange", SubCategory = "Blood Orange" });
        NormalFruitList.Add(new Fruit { Category = "Orange", SubCategory = "Sweet Orange" });
        NormalFruitList.Add(new Fruit { Category = "Peach", SubCategory = "" });
        NormalFruitList.Add(new Fruit { Category = "Bananas", SubCategory = "" });
        NormalFruitList.Add(new Fruit { Category = "Bananas", SubCategory = "Yellow Bananas" });
        NormalFruitList.Add(new Fruit { Category = "Bananas", SubCategory = "Green Bananas" });

现在我希望合并第二个列表,如果可能的话,使用 LINQ,具体取决于第一个列表。

例如,原始列表中只有 1 个橙色条目,我希望将正常列表中的 2 个条目附加到原始列表中。香蕉也是如此。

如何使用 LINQ 实现这一目标?

感谢您的帮助和时间

------------RESULT我希望实现

//FinalResult
        //Apple
        //Red Apple
        //Green Apple
        //Orange
        //Blood Orange
        //Sweet Orange
        //Peach
        //Green Grapes
        //Black Grapes
        //Bananas
        //Yellow Banans
        //Green Bananas

【问题讨论】:

  • 什么时候是重复的?期望结果的形状是什么?
  • Henk 我将最终所需列表添加到问题中

标签: c# linq c#-4.0 linq-to-sql


【解决方案1】:

试试这个:

        var difference = NormalFruitList.Where(normFruit =>
            !OrigFruitList.Exists(
                origFruit => origFruit.Category == normFruit.Category 
                    && origFruit.SubCategory == normFruit.SubCategory));

        // If new Category is found in NormalFruitList it will be added to the end
        int index = 0;
        var result = new List<Fruit>(OrigFruitList);
        foreach (var item in difference.Reverse())
        {
            index = result.IndexOf(OrigFruitList.FirstOrDefault(fruit => fruit.Category == item.Category));
            result.Insert(index == -1 ? OrigFruitList.Count : index + 1, item);
        }

【讨论】:

  • 伊万,谢谢你的解决方案,但它不是我想要的顺序
  • 请看我更新的问题。基本上我想保留原始列表中的顺序,并附加与普通列表的差异
  • 好的,几乎可以,但是子类别的第二个列表中的顺序没有保留,例如在“血橙”之前获得“甜橙”,在“黄香蕉”之前获得“绿香蕉”
  • 另外,如果可能,所有内容都需要作为最终列表附加到 NormalList 中
  • 完美的伊万,我只需要将项目附加到 NormalList 而不是 Original,有没有比只进行普通插入更好的方法?
【解决方案2】:

如果 Fruit 是这样的结构:

var result = OrigFruitList.Union(NormalFruitList);

如果 Fruit 是这样的类:

var resul=new List<Fruit>();
foreach(var fruit in NormalFruitList)
{
    var item = OrigFruitList.firstOrDefault(p=>p.Category == fruit.Category 
                             && p.SubCategory == fruit.SubCategory));
   if(item!=null)
       resul.Add(item);
}
NormalFruitList.AddRange(result);

【讨论】:

  • 嗨,Reza,这工作不正常,有很多重复项
【解决方案3】:
var mrgList = OrigFruitList
    .Union(NormalFruitList)
    .GroupBy(n => new {n.Category, n.SubCategory}, (fruit, fruits) => fruits.First());

【讨论】:

  • 你能举个例子吗?我已经尝试加入但没有成功
  • Malmi 我喜欢您的解决方案,但我需要在列表 1 中保持相同的顺序。目前您正在将列表的差异连接到列表的末尾。请查看有关我希望达到的结果的更新问题
【解决方案4】:

假设一个水果是重复的,而另一个水果具有相同的Category SubCategory,您可以使用Enumerable.Union 和自定义IEqualityComparer&lt;Fruit&gt;

class Fruit
{
    public String Category { get; set; }
    public String SubCategory { get; set; }

    public class Comparer : IEqualityComparer<Fruit>
    {
        public bool Equals(Fruit x, Fruit y)
        {
            return y.Category == y.Category && x.SubCategory == y.SubCategory;
        }

        public int GetHashCode(Fruit obj)
        {
            return (obj.Category + obj.SubCategory).GetHashCode();
        }
    }
}

现在您可以在Union 中使用比较器:

OrigFruitList = OrigFruitList
                .Union(NormalFruitList, new Fruit.Comparer())
                .ToList();

【讨论】:

    【解决方案5】:
    var result = OrigFruitList.Union(NormalFruitList,new FruitComparer())
    
    public class FruitComparer : IEqualityComparer<Fruit>
    {       
    
      public bool Equals(Fruit x, Fruit y)
      {
          return y.Category == y.Category && x.SubCategory == y.SubCategory;
      }
    
      public int GetHashCode(Fruit f)
      {
        return (f.Category + f.SubCategory).GetHashCode();
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      • 2013-06-15
      • 1970-01-01
      相关资源
      最近更新 更多