用于检查列表的所有成员是否包含在字典的值中的 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 来实现?

  1. 加入productIds列表
.Join(productIds, 
    x => x.Key,
    y => y,
    (x, y) => x)

或检查 productDict 是否包含 productIds

中的密钥
.Where(x => productIds.Contains(x.Key)
  1. 转换为仓库清单。
  2. 扁平化仓库清单。
  3. .GroupBy 仓库编号。
  4. 使用 IsAllProductsAvailable 转换分组的仓库数据。
  5. 查询仓库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();

Sample program

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;

然后您可以:

  1. quantityByWarehouseByProductId(按字典键)与 productIds 相交,只保留 quantityByWarehouseByProductId
  2. 中的相关条目
  3. select 所有 按仓库 ID 的数量 与每个相关产品 ID 关联的内部字典条目,并使用 SelectMany()[= 展平这些集合47=]
  4. 按仓库 ID(内部字典键)对结果进行分组
  5. 仅保留 按仓库 ID 数量的条目,其中所有所需产品均有库存
  6. 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.