【问题标题】:Union Lists using IEqualityComparer使用 IEqualityComparer 的联合列表
【发布时间】:2016-04-14 15:39:51
【问题描述】:

我有两个我的班级 Nomen 列表:

var N1 = new List<Nomen>(); 
var N2 = new List<Nomen>(); 


public class Nomen
{
    public string Id;

    public string NomenCode;

    ...

    public string ProducerName;

    public decimal? minPrice;
}

我需要加入他们。我以前是这样的:

result = N2.Union(N1, new NomenComparer()).ToList();

class NomenComparer : IEqualityComparer<Nomen>
{
    public bool Equals(Nomen x, Nomen y)
    {
        return x.Equals(y);
    }

    public int GetHashCode(Nomen nomen)
    {
        return nomen.GetHashCode();
    }
}

    public override int GetHashCode()
    {
        return (Id + NomenCode + ProducerName).GetHashCode();
    }

    public bool Equals(Nomen n)
    {
        if (!String.IsNullOrEmpty(Id) && Id == n.Id) return true;

        return (NomenCode == n.NomenCode && ProducerName == n.ProducerName);
    }

如您所见,如果 Ids 或 NomenCode 和 ProducerName 相等,对我来说它就是同一个 Nomen。 现在我的任务发生了变化,如果它们相等,我需要选择 minPrice 较少的那个。请帮我解决这个问题。 尝试对 linq 做同样的事情,但失败了

        var groups = (from n1 in N1
                      join n2 in N2
                      on new { n1.Id, n1.NomenCode, n1.ProducerName } equals new { n2.Id, n2.NomenCode, n2.ProducerName }
                      group new { n1, n2 } by new { n1.Id, n1.NomenCode, n1.ProducerName } into q
                      select new Nomen()
                      {
                          NomenCode = q.Key.NomenCode,
                          ProducerName = q.Key.ProducerName,
                          minPrice = q.Min(item => item.minPrice)
                      }).ToList();

主要是因为我需要按 ID 或 {NomenCode, ProducerName} 加入列表,但我不知道该怎么做。

【问题讨论】:

  • Linq joins with OR 条件已在这篇文章中得到解答:stackoverflow.com/questions/1264993/…
  • 感谢您的评论,从来没有像这样加入过linq,以后会有用的。
  • 我会将我的评论更改为答案。 :)

标签: c# linq iequalitycomparer


【解决方案1】:

Concat、GroupBy 然后再次选择?例如(比以前更少未经测试):

var nomens = N1.Concat(N2)
    .GroupBy(n=>n, new NomenComparer())
    .Select(group=>group.Aggregate( (min,n) => min == null || (n.minPrice ?? Decimal.MaxValue) < min.minPrice ? n : min));

【讨论】:

  • 它返回十进制列表,而不是 Nomen 列表
【解决方案2】:

Linq 加入 OR 条件已在此 SO 帖子中得到解答: Linq - left join on multiple (OR) conditions

简而言之,正如 Jon Skeet 在该帖子中解释的那样,您应该执行类似的操作

from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...

【讨论】:

  • 在我的查询中仍然是正确分组的问题。第一个答案更接近。不过还是谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多