用于检查列表的所有成员是否包含在字典的值中的 LINQ
LINQ for checking whether all members of a list are contained within values from a Dictionary
假设我有一个列表 ProductId
:
12345
23456
34567
以及各个仓库中每种产品的可用数量列表,按 id:
Dictionary<ProductId,Dictionary<WarehouseId,quantity>>
我如何查看列表中所有产品的哪些仓库有库存(每个仓库的数量 >= 1)?是否可以使用 LINQ 来实现?
- 加入
productIds
列表
.Join(productIds,
x => x.Key,
y => y,
(x, y) => x)
或检查 productDict
是否包含 productIds
中的密钥
.Where(x => productIds.Contains(x.Key)
- 转换为仓库清单。
- 扁平化仓库清单。
.GroupBy
仓库编号。
- 使用
IsAllProductsAvailable
转换分组的仓库数据。
- 查询仓库
IsAllProductsAvailable = true
。
var result = productDict
.Join(productIds,
x => x.Key,
y => y,
(x, y) => x)
.Select(x => new
{
Warehouses = x.Value
.Select(y => new
{
ProductId = x.Key,
WarehouseId = y.Key,
Quantity = y.Value
})
.ToList()
})
.SelectMany(x => x.Warehouses)
.GroupBy(x => x.WarehouseId)
.Select(g => new
{
WarehouseId = g.Key,
IsAllProductsAvailable = g.All(x => x.Quantity >= 1),
Products = g.ToList()
})
.Where(x => x.IsAllProductsAvailable)
.ToList();
Output
[{
"WarehouseId": 3,
"IsAllProductsAvailable": true,
"Products": [
{"ProductId":12345,"WarehouseId":3,"Quantity":1},
{"ProductId":23456,"WarehouseId":3,"Quantity":50},
{"ProductId":34567,"WarehouseId":3,"Quantity":20}
]
}]
假设您有以下字段:
List<int> productIds;
Dictionary<int, Dictionary<int, int>> quantityByWarehouseByProductId;
然后您可以:
- 将
quantityByWarehouseByProductId
(按字典键)与 productIds
相交,只保留 quantityByWarehouseByProductId
中的相关条目
- select 所有 按仓库 ID 的数量 与每个相关产品 ID 关联的内部字典条目,并使用
SelectMany()
[= 展平这些集合47=]
- 按仓库 ID(内部字典键)对结果进行分组
- 仅保留 按仓库 ID 数量的条目,其中所有所需产品均有库存
- select仓库ID
如下:
IEnumerable<int> warehouseIdsWithAllProductsInStock = quantityByWarehouseByProductId
.IntersectBy(productIds, qbwForPid => qbwForPid.Key)
.SelectMany(qbwForPid => qbwForPid.Value)
.GroupBy(qbw => qbw.Key)
.Where(qsbw => qsbw.All(qbw => qbw.Value >= 1))
.Select(qsbw => qsbw.Key);
为了使名称尽量简短,我在示例中使用了以下缩写:
qbwForPid
:产品 ID 的仓库数量
qbw
: 按仓库数量
qsbw
:仓库数量
注意:此方法假定所有现有仓库 ID 都存在于内部字典的 KeyValuePair
中。
示例 fiddle here.
假设我有一个列表 ProductId
:
12345
23456
34567
以及各个仓库中每种产品的可用数量列表,按 id:
Dictionary<ProductId,Dictionary<WarehouseId,quantity>>
我如何查看列表中所有产品的哪些仓库有库存(每个仓库的数量 >= 1)?是否可以使用 LINQ 来实现?
- 加入
productIds
列表
.Join(productIds,
x => x.Key,
y => y,
(x, y) => x)
或检查 productDict
是否包含 productIds
.Where(x => productIds.Contains(x.Key)
- 转换为仓库清单。
- 扁平化仓库清单。
.GroupBy
仓库编号。- 使用
IsAllProductsAvailable
转换分组的仓库数据。 - 查询仓库
IsAllProductsAvailable = true
。
var result = productDict
.Join(productIds,
x => x.Key,
y => y,
(x, y) => x)
.Select(x => new
{
Warehouses = x.Value
.Select(y => new
{
ProductId = x.Key,
WarehouseId = y.Key,
Quantity = y.Value
})
.ToList()
})
.SelectMany(x => x.Warehouses)
.GroupBy(x => x.WarehouseId)
.Select(g => new
{
WarehouseId = g.Key,
IsAllProductsAvailable = g.All(x => x.Quantity >= 1),
Products = g.ToList()
})
.Where(x => x.IsAllProductsAvailable)
.ToList();
Output
[{
"WarehouseId": 3,
"IsAllProductsAvailable": true,
"Products": [
{"ProductId":12345,"WarehouseId":3,"Quantity":1},
{"ProductId":23456,"WarehouseId":3,"Quantity":50},
{"ProductId":34567,"WarehouseId":3,"Quantity":20}
]
}]
假设您有以下字段:
List<int> productIds;
Dictionary<int, Dictionary<int, int>> quantityByWarehouseByProductId;
然后您可以:
- 将
quantityByWarehouseByProductId
(按字典键)与productIds
相交,只保留quantityByWarehouseByProductId
中的相关条目
- select 所有 按仓库 ID 的数量 与每个相关产品 ID 关联的内部字典条目,并使用
SelectMany()
[= 展平这些集合47=] - 按仓库 ID(内部字典键)对结果进行分组
- 仅保留 按仓库 ID 数量的条目,其中所有所需产品均有库存
- select仓库ID
如下:
IEnumerable<int> warehouseIdsWithAllProductsInStock = quantityByWarehouseByProductId
.IntersectBy(productIds, qbwForPid => qbwForPid.Key)
.SelectMany(qbwForPid => qbwForPid.Value)
.GroupBy(qbw => qbw.Key)
.Where(qsbw => qsbw.All(qbw => qbw.Value >= 1))
.Select(qsbw => qsbw.Key);
为了使名称尽量简短,我在示例中使用了以下缩写:
qbwForPid
:产品 ID 的仓库数量qbw
: 按仓库数量qsbw
:仓库数量
注意:此方法假定所有现有仓库 ID 都存在于内部字典的 KeyValuePair
中。
示例 fiddle here.