cdxf
cdxf

Reputation: 5648

How to filter only a element from a sequence (IEnumerable) in LINQ

For example: { 1,2,3,4,5,3,6}.Filter(i => i.Equals(3)) will become {1,2,4,5,3,6}

My current way:

array
.TakeWhile(i => !i.Equals(min))
.Concat(array.SkipWhile(i => !i.Equals(min)).Skip(1))

I hope there is some way that will more elegant(shorter) than this

Upvotes: 0

Views: 974

Answers (4)

teo van kot
teo van kot

Reputation: 12491

Just add Extension and more general method for @George Alexandria great answer:

public static class LinqExtentions
{
    public static IEnumerable<T> RemoveNumberByCondition<T>(this IEnumerable<T> collection,
       Func<T, bool> predicate, 
       int numberToRemove = 1)
    {
        var count = 0;
        return collection.Where(x => predicate(x) || ++count > numberToRemove).ToArray();
    }
}

Usage:

var min = 3;
var arr = new[] { 1, 2, 3, 4, 5, 3, 6 };
var res = arr.RemoveNumberByCondition(x => !x.Equals(min));

Upvotes: 1

Filip Cordas
Filip Cordas

Reputation: 2561

I don't know where filter works like this but this what I use if I want to remove one item only from IEnumerable.

public static class LinqExtensions
    {
        public static IEnumerable<TSource> RemoveOne<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            var found = false;
            foreach (var item in source)
            {
                if (!found && predicate(item))
                {
                    found = true;
                }
                else
                {
                    yield return item;
                }
            }
        }
    }

Upvotes: 2

tinudu
tinudu

Reputation: 1199

public static class LinqExtensions
{
    public static IEnumerable<TSource> SkipFirstWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (predicate == null) throw new ArgumentNullException(nameof(predicate));
        return SkipFirstWhereIterator(source, predicate);
    }

    private static IEnumerable<TSource> SkipFirstWhereIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        using (var e = source.GetEnumerator())
        {
            while (true)
            {
                if (!e.MoveNext()) yield break;
                if (predicate(e.Current)) break;
                yield return e.Current;
            }
            while (e.MoveNext())
                yield return e.Current;
        }
    }
}

Upvotes: 0

George Alexandria
George Alexandria

Reputation: 2936

Well, for more clear reading I think will be better if I will post it as answer not a comment.

var array = new List<int> { 1, 2, 3, 4, 5, 3, 6 };
int count = 0; 
array = array.Where(i => !i.Equals(3) || count++ > 0).ToList();

Upvotes: 5

Related Questions