【问题标题】:Join two lists using linq queries - C#使用 linq 查询加入两个列表 - C#
【发布时间】:2016-03-01 06:04:24
【问题描述】:

我有一个任务,我必须加入两个相同类型的列表(客户)。他们有相似的条目,我必须避免重复。

这是我的客户类:

class Customer
{
  private String _fName, _lName;
  private int _age, _cusIndex;
  private float _expenses;

  public Customer(String fName, String lName, int age, float expenses, int cusIndex)
  {
    this._fName = fName;
    this._lName = lName;
    this._age = age;
    this._expenses = expenses;
    this._cusIndex = cusIndex;
  }
}

所以我有两个List<Customer>s,分别命名为customers1customers2。我需要在不使用 Collections 方法的情况下加入这两个(例如 customer1.Union(customer2).ToList(); 但使用 Linq 查询。

这是我写的 Linq 查询

var joined = (from c1 in customers1
              join c2 in customers2
              on c1.CusIndex equals c2.CusIndex
              select new {c1, c2});

但这给了我同时出现在两个列表中的成员。但我需要所有,没有重复。有什么解决办法???

【问题讨论】:

  • 1.在Customer 类中覆盖EqualsGetHashCode(以反映两个客户被视为相等,如果他们的CusIndex 相等)。 2.var joined = customers1.Concat(customers2).Distinct();
  • 看起来Union 方法没有等效的查询。不使用Union方法的原因是什么?
  • @Corak 是的。我已经这样做了。但问题是,此查询返回两个列表中的客户。但我需要每个人
  • @ThisaruGuruge - Concat 基本上只是枚举整个第一个可枚举然后整个第二个可枚举。 Distinct 然后基本上会跳过所有已经产生的元素。这给了你,你想要的:everyone(来自两个列表),但只有一次。但是由于Union 似乎对你有用(我想它在引擎盖下也是如此),使用它。 :)
  • 是的,根据referencesource 确实如此。相关实现(查找UnionIterator):Set<TSource> set = new Set<TSource>(comparer); foreach (TSource element in first) if (set.Add(element)) yield return element; foreach (TSource element in second) if (set.Add(element)) yield return element;

标签: c# linq list join linq-query-syntax


【解决方案1】:

为什么不使用 Distinct 过滤掉重复项?

 var joined =  (from c1 in customers1
          join c2 in customers2
          on c1.CusIndex equals c2.CusIndex
          select new {c1, c2}).Distinct();

Microsoft.Ajax.Utilities 中有一个不错的extension。它有一个名为DistinctBy 的函数,它可能与您的情况更相关。

【讨论】:

  • 我用过这个。但是当我尝试使用ToList() 方法将其转换为新列表时,它给了我错误。 cannot implicitly convert type
  • 这类似于self join。 ToList() 会给你一个匿名集合。我对您要达到的目标感到困惑。您不能将匿名类型强制转换为已知类型。
  • 正如我所提到的,我需要加入两个没有重复元素的列表。这是任务的一部分!
  • 然后你必须Union 合并两个集合,然后Distinct 过滤掉重复项。或者你可以使用Intersect,然后是Union,然后是Except。有很多方法可以做到这一点。
  • 感谢您的帮助。我尝试并成功了@yeldarKurmangaliyev 提供的方法
【解决方案2】:

看起来Union 方法没有等效的查询。您将需要在方法链调用或查询中使用此方法。

如果您查看MSDN documentation 返回两个序列的集合并集,您将看到以下官方查询:

var infoQuery =
    (from cust in db.Customers
    select cust.Country)
    .Union
        (from emp in db.Employees
        select emp.Country)
;

因此,您的情况只有两种选择:

  1. 方法链:

    var joined = customers1.Union(customers2);
    
  2. LINQ 查询

    var joined = (from c1 in customers1
                  select c1)
                 .Union
                     (from c2 in customers2
                      select c2);
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2019-08-11
    • 2017-06-09
    • 1970-01-01
    相关资源
    最近更新 更多