使用Linq方法语法从列表中删除背靠背重复条目

本文关键字:背靠背 删除 方法 Linq 语法 列表 使用 | 更新日期: 2023-09-27 18:09:13

我有一个可能包含重复条目的状态更改列表,我需要过滤下来,删除背对背发生的重复项。

希望有几个示例列表将演示我想使用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与日期,OldStatus和NewStatus,但我担心日期会在秒内变化,我仍然想排除'背对背相同' (OldStatus/NewStatus)条目。

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

使用Linq方法语法从列表中删除背靠背重复条目

如果当前项不等于最后添加的项,可以使用Aggregate: add items to the cumulative list:

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;
    });

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

// 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));