我正在尝试对对象列表进行分组,这些对象具有作为列表的属性。使用以下表达式时,它不会将具有列表的对象分组在一起,大概是因为当检查每个列表的相等性时,即使内容相同,也不匹配。
我知道这是问题所在,好像我停止对列表进行分组一样,代码输出的是两个项目而不是三个。
如何调整我的表达式,以便正确地将前两个项(相同)分组为一个?
public class Item {
public string Id { get; set; }
public string Name { get; set; }
public IEnumerable<ChildItem> Children { get; set; }
}
public class ChildItem {
public string ChildItemName { get; set; }
}
var items = new List<Item> {
new Item {
Id = "00001",
Name = "My Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 1" },
new ChildItem { ChildItemName = "string 2" },
}
},
new Item {
Id = "00001",
Name = "My Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 1" },
new ChildItem { ChildItemName = "string 2" },
}
},
new Item {
Id = "00002",
Name = "My Second Item",
Children = new List<ChildItem> {
new ChildItem { ChildItemName = "string 3" },
}
}
};
var result =
from c in items
group c by new
{
c.Id,
c.Name,
c.Children,
}
into gcs
select new Item()
{
Id = gcs.Key.Id,
Name = gcs.Key.Name,
Children = gcs.Key.Children
};
如果具有相同ID的项目具有相同的名称和集合,则可以按ID分组,然后采用该组的第一项
IEnumerable<Item> uniqueItems = items
.GroupBy(x => x.Id)
.Select(g => g.First());
您无需将所有内容都放入组密钥。
根据您的评论,由于Id
不能保证唯一性,因此您必须提供自己对“相等”含义的定义。您可以通过实现自己的相等比较器来做到这一点。
ChildItem
作为singleton的实现,因为它将在中重复使用ItemEqualityComparer.Equals
。
class ChildItemEqualityComparer : IEqualityComparer<ChildItem>
{
public static readonly ChildItemEqualityComparer Instance =
new ChildItemEqualityComparer(); // Create singleton.
private ChildItemEqualityComparer() { } // Hide constructor.
public bool Equals(ChildItem x, ChildItem y) =>
String.Equals(x.ChildItemName, y.ChildItemName);
public int GetHashCode(ChildItem childItem) =>
childItem.ChildItemName?.GetHashCode() ?? 0;
}
一个实现Item
:
class ItemEqualityComparer : IEqualityComparer<Item>
{
public bool Equals(Item x, Item y)
{
return x.Id == y.Id && x.Name == y.Name &&
Enumerable.SequenceEqual(x.Children, y.Children,
ChildItemEqualityComparer.Instance);
}
public int GetHashCode(Item item)
{
int hash = 43;
unchecked {
hash = 17 * hash + (item.Id?.GetHashCode() ?? 0);
hash = 17 * hash + (item.Name?.GetHashCode() ?? 0);
foreach (ChildItem childItem in item.Children) {
hash = 17 * hash + ChildItemEqualityComparer.Instance.GetHashCode(childItem);
}
}
return hash;
}
}
和查询:
var result = items.Distinct(new ItemEqualityComparer());
这产生2个项目。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句