简体   繁体   English

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

[英]How to remove items in a generic list from start until a specific condition

I have a generic list such as below, 我有如下通用列表,

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

I would like to remove items from the list. 我想从列表中删除项目。 It will start first item of the list. 它将从列表的第一项开始。 It will remove items until next quantity of item is greater then zero. 它将删除项目,直到下一个项目数量大于零为止。 It should do the same job reverse. 它应该做同样的事情。

It is like string.Trim('0') . 就像string.Trim('0')

My result should be like below : 我的结果应如下所示:

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

You want something like this: 您想要这样的东西:

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

This would be the "simple" solution I guess. 我猜这将是“简单”的解决方案。 It would be faster to search for the bounds of the desired range of steps first and then get that using GetRange . 首先搜索所需steps范围的边界,然后使用GetRange获取该范围会更快。

I think, the best option is reassign step to new list 我认为,最好的选择是将step重新分配到新列表

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

UPD : Yeah, my fault, I made TrimStart only. UPD :是的,我的错,我只做过TrimStart Was inattention. 注意力不集中。

This should do the trick: 这应该可以解决问题:

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

The SkipWhile first skips all steps with quantity=0, then it takes all steps so long as there are following steps with a quantity != 0. SkipWhile首先跳过数量为0的所有步骤,然后执行所有步骤,只要后面的数量为!= 0的步骤即可。

Whilst the simple solution would be to revere the list twice that could get expensive for large lists. 尽管简单的解决方案是重新列出该列表两次,这对于大型列表而言可能会变得昂贵。

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

A more efficient solution would be to define an extension method like this: 一个更有效的解决方案是定义一个扩展方法,如下所示:

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

then call it: list = list.SkipWhile(s => s.Quantity == 0).TrimLast(s => s.Quantity == 0).ToList(); 然后调用它: list = list.SkipWhile(s => s.Quantity == 0).TrimLast(s => s.Quantity == 0).ToList(); This has the advantage of never storing more than the longest consecutive sequence of zeros unlike the reverse solution which needs to store the whole list twice. 与反向解决方案需要两次存储整个列表不同,它的优点是永远不会存储比最长的连续零序列更多的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM