Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take to specific element in array

Tags:

c#

linq

This is my sample data

var array = new string[]  { "q", "we", "r", "ty", " ", "r" };

I want to take items from this collection until one of them don't meet the criteria, for example:

x => string.IsNullOrEmpty(x);

So after this:

var array = new string[]  { "q", "we", "r", "ty", " ", "r" };
var newArray = array.TakeTo(x => string.IsNullOrEmpty(x));

newArray should contains: "q", "we", "r", "ty"

I created this code:

public static class Extensions
{
    public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate)
    {
        if (items == null) throw new ArgumentNullException("items");
        if (predicate == null) throw new ArgumentNullException("predicate");

        var retVal = 0;
        foreach (var item in items)
        {
            if (predicate(item)) return retVal;
            retVal++;
        }
        return -1;
    }

    public static IEnumerable<TSource> TakeTo<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        var index = source.FindIndex(predicate);

        if (index == -1)
            return source;

        return source.Take(index);
    }
}

var array = new string[]  { "q", "we", "r", "ty", " ", "r" };
var newArray = array.TakeTo(x => string.IsNullOrEmpty(x));

It works, but I am wondering if there is any built-in solution to that. Any ideas?

like image 718
dafie Avatar asked Dec 19 '25 07:12

dafie


1 Answers

juharr mentioned in a comment that you should use TakeWhile, and it's likely exactly what you're looking for.

For your case, the code you'd be looking for is:

var array = new string[]  { "q", "we", "r", "ty", " ", "r" };
var newArray = array.TakeWhile(x => !string.IsNullOrWhiteSpace(x)).ToArray();

Notably, I've replaced IsNullOrEmpty with an IsNullOrWhiteSpace call, which is important as IsNullOrEmpty will return false if there's any whitespace present.

What TakeWhile does is essentially iterate through an enumerable's elements and subjects them to your given function, adding to a return collection until the function no longer returns true, at which point it stops iterating through the elements and returns what it's collected so far. In other words, it's "taking, while..." your given condition is met.

In your example, TakeWhile would stop collecting on your array variable's 4th index, since it contains only whitespace, and return "q", "we", "r", "ty".

like image 156
Spevacus Avatar answered Dec 20 '25 20:12

Spevacus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!