我想创建一个NEW,DELETED,COMMON项目的分组列表。我目前这样做:
public class ListSortingGroupingTest
{
List<int> OldList = new List<int> { 1, 2, 3, 4, 5 };
List<int> NewList = new List<int> { 3, 4, 5, 7, 8, 9 };
public void CreateGroupedList()
{
var deleted = OldList.Except(NewList).Select(i => new { Group = "Deleted", Number = i });
var added = NewList.Except(OldList).Select(i => new { Group = "Added", Number = i});
var common = NewList.Intersect(OldList).Select(i => new { Group = "Common", Number = i});
var result = deleted.Union(added).Union(common);
}
}
这很有效。但我想知道是否有更好或更有效的方式?
最终我希望在WPF Grouped ListView中绑定它。
答案 0 :(得分:2)
您当前的方法是提取新旧集合(即唯一序列)值之间变化信息的标准和自然方式。由于基于哈希查找的实现,使用的LINQ集合运算符(Except
和Intersect
)非常有效。虽然3次调用将在内部创建3个哈希集,但复杂性仍为O(N+M)
。唯一的改进是使用Concat
而不是Union
,因为之前的方法会唯一地分隔值。
更高效的方式(但仍然是O(N+M)
)可以将旧项和新项连接到指定值是旧还是新的附加属性,然后按值分组并确定添加/删除/共同基于分组计数和内容的状态 - 具有2个值的组是常见的,对于具有单个值的组,添加/删除的组取决于值是新的还是旧的:
var result = OldList.Select(x => new { Value = x, IsNew = false })
.Concat(NewList.Select(x => new { Value = x, IsNew = true }))
.GroupBy(x => x.Value)
.Select(g => new
{
Group = g.Count() > 1 ? "Common" : g.First().IsNew ? "Added" : "Deleted",
Number = g.Key
});
答案 1 :(得分:0)
试试这个。
var result = OldList.Union(NewList).Select(n => new
{
Group = OldList.Contains(n) && NewList.Contains(n) ? "Common" : (OldList.Contains(n)) ? "Deleted" : "Added",
Number = n
}).ToList();