如何使用 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());
}
}
我首先找到重复的商店,它会在对象内部包含计数 = 2 的重复商店的对象,然后按商店编号和不同商店的仓库编号分组,仓库计数仍为 2,但对于同一商店和仓库是重复的,它将是 count = 1,所以我发现 count > 1 这样我就可以找到重复项并检查 Isresolved 在解决后不要再次拉同一个商店。
下面是fiddle:
如果我没理解错的话。下面就给你想要的。
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);
试试这个,使用 LINQ 的 GroupBy().Select().Where()
根据我假设您需要的标准对对象列表进行分组和过滤,给定您显示的输出。
描述:
GroupBy() =>
Groups the objects using the StoreNumber
property.
Select() =>
Selects the objects where the
IsResolved
property is false
Where() =>
Filters the
objects that have more than 1 elements with different
WarehouseNumber
SelectMany()=>
Flattens the Grouping, to have
all the matching objects in a sequential view
如果需要,可以添加 OrderBy()
以对 StoreNumber
ThenBy()
WarehouseNumber
.
上的列表进行排序
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
结果中,并会在其中包含重复项。
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());
}
}
我首先找到重复的商店,它会在对象内部包含计数 = 2 的重复商店的对象,然后按商店编号和不同商店的仓库编号分组,仓库计数仍为 2,但对于同一商店和仓库是重复的,它将是 count = 1,所以我发现 count > 1 这样我就可以找到重复项并检查 Isresolved 在解决后不要再次拉同一个商店。
下面是fiddle:
如果我没理解错的话。下面就给你想要的。
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);
试试这个,使用 LINQ 的 GroupBy().Select().Where()
根据我假设您需要的标准对对象列表进行分组和过滤,给定您显示的输出。
描述:
如果需要,可以添加
GroupBy() =>
Groups the objects using theStoreNumber
property.
Select() =>
Selects the objects where theIsResolved
property isfalse
Where() =>
Filters the objects that have more than 1 elements with differentWarehouseNumber
SelectMany()=>
Flattens the Grouping, to have all the matching objects in a sequential view
OrderBy()
以对 StoreNumber
ThenBy()
WarehouseNumber
.
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
结果中,并会在其中包含重复项。