使用 IEqualityComparer 的联合列表
Union Lists using IEqualityComparer
我有两个 class 姓名列表:
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} 加入列表,但我不知道该怎么做。
Concat、GroupBy 然后再 Select?例如(比以前更少未经测试):
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));
此 SO post 中回答了带有 OR 条件的 Linq 连接:
Linq - left join on multiple (OR) conditions
简而言之,正如 Jon Skeet 在 post 中解释的那样,您应该做类似
的事情
from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...
我有两个 class 姓名列表:
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} 加入列表,但我不知道该怎么做。
Concat、GroupBy 然后再 Select?例如(比以前更少未经测试):
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));
此 SO post 中回答了带有 OR 条件的 Linq 连接: Linq - left join on multiple (OR) conditions
简而言之,正如 Jon Skeet 在 post 中解释的那样,您应该做类似
的事情from a in tablea
from b in tableb
where a.col1 == b.col1 || a.col2 == b.col2
select ...