Reputation: 3283
I have a collection of objects with properties and I want to remove all the trailing objects with (say) a value of 0
in LINQ.
public class Object
{
public Object(){}
public int Property {get; set;}
}
and if I have a list of objects:
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"
How would I go about removing the "trailing zeros" in this list? I don't want to remove all properties with a zero, but I want to remove any objects from the list with a property value of zero if it it is not later followed by a property value of something greater.
Upvotes: 4
Views: 938
Reputation: 28835
Write an extension method:
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;
}
}
}
}
Then, if you have an IEnumerable<Object>
called l
, you would call TrimTrailing
using
var trimmed = l.TrimTrailing(o => o.Property == 0);
Be careful with this, though: in the worst case, it buffers all the items from items
and then throws away the buffer.
Upvotes: 4
Reputation: 190976
Just iterate your list backwards removing any 0
entries and stop either at the beginning of the list or the Property != 0
.
for (int i = list.Count - 1; i >= 0; i--)
{
var item = list[i];
if (item.Property == 0)
{
list.RemoveAt(i);
}
else
{
break;
}
}
This will allow for a single pass through your list.
Upvotes: 3
Reputation: 15982
You can use FindLastIndex
to find the last non-0
index, and Take
the elements up to that.
var result = list.Take(list.FindLastIndex(x => x.Property != 0) + 1);
Upvotes: 1
Reputation: 100545
Standard solution for sequences of finite size - reverse, remove from start, reverse:
var withoutTail = sequence
.Reverse()
.SkipWhile( x => x == 0) // whatever condition you need
.Reverse();
This is very non-optimal, so if you actually have real collection (i.e. List
) it would be better to just remove items starting from last index.
Upvotes: 8