如何从开始直到特定条件中删除通用列表中的项

本文关键字:删除 列表 特定条件 开始 | 更新日期: 2023-09-27 18:06:16

我有一个像下面这样的通用列表,

var steps = new List<Step> 
{
    new Step { From = "A", To = "D", Quantity = 0 }, 
    new Step { From = "D", To = "J", Quantity = 0 }, 
    new Step { From = "J", To = "T", Quantity = 0 },
    new Step { From = "D", To = "K", Quantity = 0 }, 
    new Step { From = "K", To = "T", Quantity = 0 },
    new Step { From = "E", To = "K", Quantity = 0 },
    new Step { From = "A", To = "E", Quantity = 0 },
    new Step { From = "B", To = "E", Quantity = 0 },
    new Step { From = "E", To = "L", Quantity = 5 },
    new Step { From = "B", To = "F", Quantity = 5 },
    new Step { From = "B", To = "G", Quantity = 5 },
    new Step { From = "F", To = "I", Quantity = 5 },
    new Step { From = "G", To = "I", Quantity = 5 },
    new Step { From = "C", To = "H", Quantity = 0 },
    new Step { From = "H", To = "Z", Quantity = 0 },
    new Step { From = "H", To = "Y", Quantity = 0 },
    new Step { From = "H", To = "X", Quantity = 5 },
    new Step { From = "X", To = "I", Quantity = 5 },
    new Step { From = "I", To = "V", Quantity = 5 },
    new Step { From = "L", To = "V", Quantity = 5 },
    new Step { From = "Y", To = "V", Quantity = 5 },
    new Step { From = "Y", To = "M", Quantity = 0 },
    new Step { From = "Z", To = "M", Quantity = 0 },
    new Step { From = "Z", To = "N", Quantity = 0 },
    new Step { From = "M", To = "O", Quantity = 0 },
};

我想从列表中删除项目。它将开始列表的第一个项目。它将删除项目,直到下一个项目的数量大于零。它应该反过来做同样的工作。

就像string.Trim('0')

结果应该如下所示:

var steps = new List<Step> 
{
    new Step { From = "E", To = "L", Quantity = 5 },
    new Step { From = "B", To = "F", Quantity = 5 },
    new Step { From = "B", To = "G", Quantity = 5 },
    new Step { From = "F", To = "I", Quantity = 5 },
    new Step { From = "G", To = "I", Quantity = 5 },
    new Step { From = "C", To = "H", Quantity = 0 },
    new Step { From = "H", To = "Z", Quantity = 0 },
    new Step { From = "H", To = "Y", Quantity = 0 },
    new Step { From = "H", To = "X", Quantity = 5 },
    new Step { From = "X", To = "I", Quantity = 5 },
    new Step { From = "I", To = "V", Quantity = 5 },
    new Step { From = "L", To = "V", Quantity = 5 },
    new Step { From = "Y", To = "V", Quantity = 5 },
};

如何从开始直到特定条件中删除通用列表中的项

您想要这样的内容:

steps = steps.SkipWhile(s => s.Quantity == 0).Reverse()
             .SkipWhile(s => s.Quantity == 0).Reverse()
             .ToList();

我想这将是"简单"的解决方案。首先查找steps的期望范围的边界,然后再使用GetRange得到该范围的边界,这样会更快。

我认为,最好的选择是重新分配step到新的列表

list = list.SkipWhile(s => s.Quantity == 0).ToList();

UPD:是的,我的错,我只做了TrimStart。注意力不集中。

这应该能奏效:

steps = steps
    .SkipWhile(step => step.Quantity == 0)
    .TakeWhile((step, index) =>
        steps.Skip(index).Any(nextSteps => nextSteps.Quantity != 0))
    .ToList();

SkipWhile首先跳过所有quantity=0的步骤,然后执行所有以下步骤中quantity=0的步骤

虽然简单的解决方案是重复两次列表,但对于大列表来说可能会变得昂贵。

list = list.SkipWhile(s => s.Quantity == 0).Reverse()
              .SkipWhile( s => s.Quantity == 0).Reverse().ToList();
一个更有效的解决方案是这样定义一个扩展方法:
public static IEnumerable TrimLast(IEnumerable<T> this, Func<T, Bool> cond) {
    foreach (var item in this) {
       if (!cond(item)) {
           foreach (var storeditem in store) {
               yield return storeditem;
           }
           store.Clear;
           yield return item;
       } else {
           store.Add(item);
       }
    }
}

则称其为:list = list.SkipWhile(s => s.Quantity == 0).TrimLast(s => s.Quantity == 0).ToList();这样做的优点是永远不会存储超过最长的连续零序列,而不像反向解决方案需要存储整个列表两次。