C# 使用Linq方法语法从列表中删除背靠背重复项

C# 使用Linq方法语法从列表中删除背靠背重复项,c#,linq,C#,Linq,我有一个状态更改列表,其中可能包含重复的条目,我需要对这些条目进行筛选以删除背靠背发生的重复条目 希望有两个示例列表将演示我想使用linq方法语法实现什么 Original List with duplicate entries (Id's 2 and 3 are dups) Id Date OldStatus NewStatus =====================================================

我有一个状态更改列表,其中可能包含重复的条目,我需要对这些条目进行筛选以删除背靠背发生的重复条目

希望有两个示例列表将演示我想使用linq方法语法实现什么

Original List with duplicate entries (Id's 2 and 3 are dups)
Id      Date                    OldStatus       NewStatus
=========================================================
1       9/28/2016 10:00:00 AM   Requested       Quoted
2       9/28/2016 10:15:00 AM   Quoted          Rejected
3       9/28/2016 10:15:01 AM   Quoted          Rejected
4       9/28/2016 10:30:00 AM   Rejected        Requested
5       9/28/2016 10:30:00 AM   Requested       Quoted
6       9/28/2016 10:45:00 AM   Quoted          Rejected
7       9/28/2016 10:50:00 AM   Rejected        Requested
8       9/28/2016 10:50:00 AM   Requested       Quoted
9       9/28/2016 10:50:00 AM   Quoted          Purchased

Desired List (Id 3 removed)

Id      Date                    OldStatus       NewStatus
=========================================================
1       9/28/2016 10:00:00 AM   Requested       Quoted
2       9/28/2016 10:15:00 AM   Quoted          Rejected
4       9/28/2016 10:30:00 AM   Rejected        Requested
5       9/28/2016 10:30:00 AM   Requested       Quoted
6       9/28/2016 10:45:00 AM   Quoted          Rejected
7       9/28/2016 10:50:00 AM   Rejected        Requested
8       9/28/2016 10:50:00 AM   Requested       Quoted
9       9/28/2016 10:50:00 AM   Quoted          Purchased
我曾考虑将GroupBy与Date、OldStatus和NewStatus一起使用,但我担心日期会以秒为单位变化,我仍然希望排除“背对背相同”(OldStatus/NewStatus)条目


使用linq方法语法删除这些背对背条目的eligant解决方案是什么?

您可以使用
聚合
:如果当前项不等于最后添加的项,则将项添加到累积列表:

var result = list.Aggregate(new List<StatusChange>(),
    (lst, i) =>
    {
        var last = lst.LastOrDefault();
        if (last == null
                || (last.Id != i.Id 
                    && last.OldStatus != i.OldStatus
                    && last.NewStatus != i.NewStatus))
        {
            lst.Add(i);
        }
        return lst;
    });
var result=list.Aggregate(新列表(),
(lst,i)=>
{
var last=lst.LastOrDefault();
if(last==null
||(last.Id!=i.Id
&&last.OldStatus!=i.OldStatus
&&last.NewStatus!=i.NewStatus)
{
第1段添加(i);
}
返回lst;
});

在这个解决方案中,您可以两两迭代并检查对。如果在一对中,两个项目都具有相同的
OldStatus
NewStatus
,则将它们添加到副本集合中。迭代完成后,将从
状态
集合中删除重复项:

// Find duplicates.
var duplicates = statuses
    .Zip(statuses.Skip(1), (s1, s2) => Tuple.Create(s1, s2))
    .Where(pair => 
        pair.Item1.NewStatus == pair.Item2.NewStatus && 
        pair.Item1.OldStatus == pair.Item2.OldStatus)
    .Select(pair => pair.Item2);

// Remove the duplicates from the original collection of the status changes.
statuses.RemoveAll(s => duplicates.Contains(s));

Id 6也是
OldStatus=Quoted
NewStatus=Rejected
。这难道不应该被删除吗?@PiotrWolkowski不,这不是背对背的重复。因此,如果分钟值不同,那么这不被认为是重复的,但是如果第二个值不同,那么它是重复的?如果背对背条目Id=n&Id=n+1包含相同的OldStatus和NewStatus值,那么它被认为是重复的。除了那个用例之外的任何东西,它都不是复制品。否决票投给了什么?解决方案正在运行并提供问题中的功能。