从列表中删除<>;重复项目并记录重复数量
本文关键字:项目 记录 列表 删除 lt gt | 更新日期: 2023-09-27 18:00:24
我有一个List<Item>
。Item
具有属性Id
、Name
和Amount
。此列表中存在重复项目。我需要得到一个新的List<Item>
,它只包含不重复的Item
s,并且在Item
的Amount
中应该是它在第一个List<Item>
中重复的次数。我试过类似的东西
for (int i = 0; i < list.Count; i++)
{
for (int j = 0; j < list.Count; j++)
{
if (list[i].Name == list[j].Name)
{
list.Remove(prod.Components[j]);
list[i].Amount++;
}
}
}
但是在这个循环中存在一些问题。我的大脑过热了。请帮帮我。
一个简单的LINQ查询可以获得唯一的项目以及它们出现的次数:
var distinct = list.GroupBy(o => o.Name)
.Select(g => new { Count = g.Count(), Item = g.First() })
.ToList();
然后,您可以将每个项目的Amount
修改为重复次数:
foreach (var row in distinct)
{
row.Item.Amount = row.Count;
}
最后取回一个不包含重复项且数量正确的List<Item>
:
var uniqueItems = distinct.Select(r => r.Item).ToList();
重要信息:上面的代码假设"重复"项彼此无法区分,但没有其他区别(例如,它不需要Item
具有默认构造函数)。根据具体情况,可以用更短的形式写出来。
此外,Amount
属性在这里看起来很奇怪。由于副本不保证其金额的总和,Item.Amount
的目的是什么?我假设数量为2的重复项目应该会导致一个数量为4的项目,但您的代码不能做到这一点(我的代码遵循这一点)。
我突然想到(还没有测试过):
list.GroupBy(x => x.Name)
.Select(x => new Item {
Name = x.Key,
Amount = x.Count()
})
.ToList();
你没有具体说明ID会发生什么,所以我忽略了它们。
(请注意,这将创建一个新列表,而不是修改原始列表)。
试试这样的东西:
var groups = from item in items
group item by item.Property
into grouped
select grouped;
var distinct = from g in groups
let item = g.First()
let amount = g.Count()
select new Item {Property = item.Property, Amount = amount};
之后CCD_ 16包含CCD_ 17及其来自原始项目列表的金额。
foreach(var item in list)
{
if(list.Count(e=>e.Id == item.Id && e.Name == item.Name)!=1)
{
list.Remove(item);
}
}
假设您通过前两个属性ID
和Name
来确定重复项。
您可以实现IEqualityComparer<Item>
并将其用于Enumerable.GroupBy
:
var itemAmounts = items.GroupBy(i => i, new Item())
.Select(g => new Item {
ID = g.First().ID,
Name = g.First().Name,
Amount = g.Count()
});
这是您的Item类,它具有IEqualityComparer<Item>
:的一个有意义的实现
class Item : IEqualityComparer<Item>
{
public int ID;
public string Name;
public int Amount;
public bool Equals(Item x, Item y)
{
if (x == null || y == null) return false;
bool equals = x.ID == y.ID && x.Name == y.Name;
return equals;
}
public int GetHashCode(Item obj)
{
if (obj == null) return int.MinValue;
int hash = 19;
hash = hash + obj.ID.GetHashCode();
hash = hash + obj.Name.GetHashCode();
return hash;
}
}
您也可以从object
覆盖Equals
和GetHasdhCode
,那么在GroupBy
:中根本不需要自定义比较器
var itemAmounts = items.GroupBy(i => i)
.Select(g => new Item {
ID = g.First().ID,
Name = g.First().Name,
Amount = g.Count()
});
您可以使用上面已经可用的方法:
public override bool Equals(object obj)
{
Item item2 = obj as Item;
if (item2 == null)
return false;
else
return Equals(this, item2);
}
public override int GetHashCode()
{
return GetHashCode(this);
}