我有一组带有属性的对象,我希望在LINQ中删除(例如)值为0
的所有尾随对象。
public class Object
{
public Object(){}
public int Property {get; set;}
}
如果我有一个对象列表:
new Object(){ Property = 1};
new Object(){ Property = 0};
new Object(){ Property = 9};
new Object(){ Property = 7};
new Object(){ Property = 0}; // "trailing zero"
new Object(){ Property = 0}; // "trailing zero"
new Object(){ Property = 0}; // "trailing zero"
如何删除此列表中的“尾随零”?我不想删除所有属性为零的属性,但我想从列表中删除属性值为零的任何对象,如果它后面没有更大的属性值。
答案 0 :(得分:6)
有限大小序列的标准解决方案 - 反向,从开始移除,反向:
var withoutTail = sequence
.Reverse()
.SkipWhile( x => x == 0) // whatever condition you need
.Reverse();
这非常不理想,所以如果你真的有真正的集合(即List
),那么从最后一个索引开始删除项目会更好。
答案 1 :(得分:4)
编写扩展方法:
static class Extensions
{
public static IEnumerable<T> TrimTrailing<T>(this IEnumerable<T> items,
Predicate<T> test)
{
if (items == null) throw new ArgumentNullException(nameof(items));
if (test == null) throw new ArgumentNullException(nameof(test));
var buf = new List<T>();
foreach (T item in items)
{
if (test(item))
{
buf.Add(item);
}
else
{
foreach (T bufferedItem in buf)
{
yield return bufferedItem;
}
buf.Clear();
yield return item;
}
}
}
}
然后,如果您有一个名为IEnumerable<Object>
的{{1}},则可以使用
l
TrimTrailing
小心这一点,但是:在最坏的情况下,它会缓冲var trimmed = l.TrimTrailing(o => o.Property == 0);
中的所有项目,然后抛弃缓冲区。
答案 2 :(得分:3)
向后迭代您的列表,删除所有Property != 0
条目,并停在列表的开头或for (int i = list.Count - 1; i >= 0; i--)
{
var item = list[i];
if (item.Property == 0)
{
list.RemoveAt(i);
}
else
{
break;
}
}
。
{{1}}
这将允许您通过列表进行单次传递。
答案 3 :(得分:1)
您可以使用FindLastIndex
查找最后一个非0
索引,以及Take
之前的元素。
var result = list.Take(list.FindLastIndex(x => x.Property != 0) + 1);