簡體   English   中英

如何使用LINQ在集合中查找重疊(不是重復,而是查找重疊)

[英]How to find overlapping in collection using LINQ ( not duplicates but to find overlaps)

List<StoreDetailDto> items = new List<StoreDetailDto>();

items.Add(new StoreDetailDto { StoreNumber = 2, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 3, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 6, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 7, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});

items.Add(new StoreDetailDto { StoreNumber = 6, WarehouseNumber = 4202, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 7, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4203, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});
items.Add(new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4207, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1"});

我在上面的集合中,商店6、9之間有重疊,但是商店7沒有重疊,這是重復項。 我發現相同的商店和不同的倉庫重疊。

為了確保我正在執行以下操作:

var overlapDupStores = items.GroupBy(
    u => u.StoreNumber,
    u => { return u; },
    (key, g) => g.ToList())
  .ToList()
  .Where(cnt => cnt.Count() > 1);


foreach (var dpovl in overlapDupStores)
{
    var stores = dpovl.Where(g => g.IsResolved != true).GroupBy(u => new { u.StoreNumber, u.WarehouseNumber }).ToList();

    if (stores.Count() > 1)
    {
        response.OverlappingStores.AddRange(stores.SelectMany(gr => gr).ToList());
    }
}

我首先找到重復的商店,它將在對象內部具有對象,其中對象的重復數為count = 2,然后按商店編號和倉庫編號分組,不同商店和倉庫的數量仍為2,但對於相同的商店和重復倉庫它將是count = 1,所以我發現count> 1,因此我可以找到重復項並檢查Isresolved是否在解決后不再再次拉同一個存儲。

以下是小提琴:

https://dotnetfiddle.net/TknnkJ

使用LINQ的GroupBy().Select().Where()嘗試此操作,根據顯示的輸出,根據我假設的條件對對象列表進行分組和過濾。

說明:

GroupBy() =>使用StoreNumber屬性對對象進行StoreNumber
Select() =>選擇IsResolved屬性為false的對象
Where() =>過濾具有超過1個元素且具有不同WarehouseNumber
SelectMany()=>平分組,以使所有匹配的對象處於順序視圖中

如果需要,可以添加OrderBy()以對StoreNumber ThenBy() WarehouseNumber上的列表進行StoreNumber

根據使用情況, Duplicates過濾器可能不正確。 可能有必要對其進行調整。

var Duplicates = 
    items.GroupBy(store => store.StoreNumber)
         .Select(grp => grp.Where(store => store.IsResolved == false))
         .Where(stores => stores.Count() > 1 && stores.Select(w => w.WarehouseNumber).Distinct().Count() == 1)
         .SelectMany(stores => stores)
         .ToList();

var Overlapping = 
    items.GroupBy(store => store.StoreNumber)
         .Select(grp => grp.Where(store => store.IsResolved == false))
         .Where(store => store.Count() > 1 && store.Select(w => w.WarehouseNumber).Distinct().Count() > 1)
         .SelectMany(stores => stores)
         .ToList();

Overlapping.ForEach(ovr =>
    Console.WriteLine($"{ovr.StoreNumber} " +
                      $"{ovr.WarehouseNumber} " +
                      $"{ovr.IsResolved} " +
                      $"{ovr.StoreName} " +
                      $"{ovr.WarehouseName}"));

Overlapping列表打印:

6 4201 False StoreEx WarehouseEx1
6 4202 False StoreEx WarehouseEx1
9 4201 False StoreEx WarehouseEx1
9 4203 False StoreEx WarehouseEx1
9 4207 False StoreEx WarehouseEx1

Duplicates列表打印:

7 4201 False StoreEx WarehouseEx1
7 4201 False StoreEx WarehouseEx1

我認為這些查詢可以完成工作:

var overlaps =
    items
        .GroupBy(x => new { x.StoreNumber, x.WarehouseNumber })
        .GroupBy(x => x.Key.StoreNumber)
        .Where(x => x.Skip(1).Any())
        .Where(x => !x.Any(y => y.Any(z => z.IsResolved)))
        .SelectMany(x => x.SelectMany(y => y))
        .ToList();

重疊

var duplicates =
    items
        .GroupBy(x => new { x.StoreNumber, x.WarehouseNumber })
        .GroupBy(x => x.Key.StoreNumber)
        .Where(x => !x.Skip(1).Any())
        .Where(x => x.First().Skip(1).Any())
        .Where(x => !x.Any(y => y.Any(z => z.IsResolved)))
        .SelectMany(x => x.SelectMany(y => y))
        .ToList();  

重復

我使用了以下源數據:

var items = new List<StoreDetailDto>()
{
    new StoreDetailDto { StoreNumber = 2, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 3, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 6, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 7, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 6, WarehouseNumber = 4202, IsResolved = true, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 7, WarehouseNumber = 4201, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4203, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
    new StoreDetailDto { StoreNumber = 9, WarehouseNumber = 4207, IsResolved = false, StoreName = "StoreEx", WarehouseName = "WarehouseEx1" },
};

值得注意的是,如果7要擁有帶有新WarehouseNumber的第三條記錄,則它將出現在overlaps結果中並將在其中包含重復項。

如果我正確理解您的意思。 以下將給您您想要的。

   var warehouseCountsByStore =
            from item in items
            group item by new { item.StoreNumber, item.WarehouseNumber } into store
            where store.Count() != 0
            select new
            {
                store.Key.StoreNumber,
                store.Key.WarehouseNumber,
                Count = store.Count()
            };

    var storesWithDuplicateWarehouses =
        from warehouse in warehouseCountsByStore
        where warehouse.Count != 1
        select new { warehouse.StoreNumber };

    var storesWithMultipleWarehouse =
        from item in items
        group item by new { item.StoreNumber } into store
        where store.Count() > 1
              && storesWithDuplicateWarehouses.Any(x => x.StoreNumber != store.Key.StoreNumber)
        select new
        {
            store.Key.StoreNumber
        };

    Console.WriteLine("Duplicates");
    foreach (var store in storesWithDuplicateWarehouses)
        Console.WriteLine(store.StoreNumber);

    Console.WriteLine("Overlap");
    foreach (var store in storesWithMultipleWarehouse)
        Console.WriteLine(store.StoreNumber);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM