簡體   English   中英

如何從開始到特定條件從通用列表中刪除項目

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

我有如下通用列表,

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首先跳過數量為0的所有步驟,然后執行所有步驟,只要后面的數量為!= 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(); 與反向解決方案需要兩次存儲整個列表不同,它的優點是永遠不會存儲比最長的連續零序列更多的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM