C# 在C列表之间执行查找,并返回匹配的最小值
我有两份清单:C# 在C列表之间执行查找,并返回匹配的最小值,c#,list,linq,C#,List,Linq,我有两份清单: var qtys = new List<InventoryQuantity>() { new InventoryQuantity() { WarehouseId = 1, QuantityInWarehouse = 0 }, new InventoryQuantity() { WarehouseId = 2, QuantityInWarehouse = 452 }, new InventoryQuantity() { WarehouseId =
var qtys = new List<InventoryQuantity>()
{
new InventoryQuantity() { WarehouseId = 1, QuantityInWarehouse = 0 },
new InventoryQuantity() { WarehouseId = 2, QuantityInWarehouse = 452 },
new InventoryQuantity() { WarehouseId = 3, QuantityInWarehouse = 184 },
new InventoryQuantity() { WarehouseId = 4, QuantityInWarehouse = 328 },
new InventoryQuantity() { WarehouseId = 5, QuantityInWarehouse = 0 },
};
var times = new List<WarehouseTransitTime>()
{
new WarehouseTransitTime() { WarehouseId = 1, TransitDays = 1 },
new WarehouseTransitTime() { WarehouseId = 2, TransitDays = 4 },
new WarehouseTransitTime() { WarehouseId = 3, TransitDays = 2 },
new WarehouseTransitTime() { WarehouseId = 4, TransitDays = 3 },
new WarehouseTransitTime() { WarehouseId = 5, TransitDays = 5 },
};
class InventoryQuantity
{
public int WarehouseId { get; set; }
public int QuantityInWarehouse { get; set; }
}
class WarehouseTransitTime
{
public int WarehouseId { get; set; }
public int TransitDays { get; set; }
}
示例数据:
qtys
时代
预期产量为3,因为3号仓库有库存和最短的运输时间2。你提到了两者之间的关系,对吗 我在考虑使用forignkey的数据库。。。但如果你的列表不太大,Linq prety会做很多事情:
keys = qtys.Where(i => i.QuantityInWarehouse > 0).Select(i => i.WarehouseId).ToList();
// get the smallest not a list
var result = times.Where(tt => keys.Contains(tt.wharehouseId)).orderby(tt => tt.Transitdays).FirstOrDefault();
否则,您可以使用ID作为键的字典…您可以这样做
var withQty = (from q in qtys
join t in times on q.WarehouseId equals t.WarehouseId
where q.QuantityInWarehouse > 0
select new { q.WarehouseId, t.TransitDays })
.OrderBy(item => item.TransitDays).FirstOrDefault();
return withQty?.WarehouseId ?? 0;
您需要的是:
功能语法
查询语法
组联接将两个列表在其对应的键上联接在一起,类似于数据库联接,并且这些键的关联值将分组为可枚举的。从该可枚举项中,您可以导出您关心的最小值,在本例中为TransitDays
在查询语法中没有与first或default等价的语法。最简单的方法就是对查询变量应用相同的OrderBy和FirstOrDefault,如上所示。在我看来,最干净、最简单的查询是:
var query =
from q in qtys
where q.QuantityInWarehouse > 0
join t in times on q.WarehouseId equals t.WarehouseId
orderby t.TransitDays
select q.WarehouseId;
var warehouseId = query.FirstOrDefault();
这给了我3。你能分享一个示例数据和它的预期结果吗?WarehouseId在两个列表中的顺序相同吗?答案很公平,但在你的查询语法中,请向我解释:这个q.WarehouseId在{}方面是对grp.Min的调用吗?我的意思是它不只是选择一个随机id,对吗?{}中的代码是否在grp为空时执行?比考虑使用?也是在Min.@Alb之前,为什么它会选择一个随机ID?分组发生在ID上,就像SQL连接一样。想象你有一袋不同颜色和大小的大理石。你一次一个地从袋子里拿出一块大理石。你挑选的每一块大理石都会被放进一堆相同颜色的大理石中。现在您有n个大理石堆,其中每一堆都由颜色设置关键帧。现在你在每一堆中寻找最小的大理石。从任何一堆大理石中拾取最小的大理石都不会改变其颜色,即键。因此,假设存在多个具有相同ID的WarehouseTransitime对象。不错。尽管在本例中,您的答案是——根据问题——忽略了函数语法部分中的第一个或第一个默认命令以及查询语法部分中的相应命令!:@Alb如果我使用Min,为什么我需要FirstOrDefault?你刚才说你返回每个ID的Min,每个堆中最小的大理石。因此,返回一个List/IEnumerable。我说的对吗?当qtys正好包含一个元素,其中数量>0时,我只尝试了qtys。Addnew InventoryQuantity{WarehouseId=2,QuantityInWarehouse=452};,我得到了一个对象引用错误;,当没有数量大于0的数量时,它在不存在任何对象引用错误的情况下工作,将.First更改为.FirstOrDefault
keys = qtys.Where(i => i.QuantityInWarehouse > 0).Select(i => i.WarehouseId).ToList();
// get the smallest not a list
var result = times.Where(tt => keys.Contains(tt.wharehouseId)).orderby(tt => tt.Transitdays).FirstOrDefault();
var withQty = (from q in qtys
join t in times on q.WarehouseId equals t.WarehouseId
where q.QuantityInWarehouse > 0
select new { q.WarehouseId, t.TransitDays })
.OrderBy(item => item.TransitDays).FirstOrDefault();
return withQty?.WarehouseId ?? 0;
var query1 = qtys.Where(q => q.QuantityInWarehouse > 0)
.GroupJoin(times, q => q.WarehouseId, t => t.WarehouseId, (q, t) => new { q.WarehouseId, TransitDays = t.DefaultIfEmpty().Min(grp => grp?.TransitDays) })
.OrderBy(g => g.TransitDays)
.FirstOrDefault();
var query2 = from q in qtys
join t in times on q.WarehouseId equals t.WarehouseId into grp
where q.QuantityInWarehouse > 0
select new
{
q.WarehouseId,
TransitDays = grp.DefaultIfEmpty().Min(g => g?.TransitDays)
};
var result = query2.OrderBy(g => g.TransitDays)
.FirstOrDefault();
var query =
from q in qtys
where q.QuantityInWarehouse > 0
join t in times on q.WarehouseId equals t.WarehouseId
orderby t.TransitDays
select q.WarehouseId;
var warehouseId = query.FirstOrDefault();