[英]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.