Combine neighboring parts of an array based on a condition
Some general remarks about your code:


combineBy use PascalCase for method names
f it's not a good parameter name, if it's a condition function they are usualy named predicate
predicate.Invoke(...) - you can call it directly with predicate(...)
values.TakeWhile(n =&gt; !predicate(n)) - do not enumerate it twice, call ToArray and use it in the subsequent lines
if you like it the LINQ way you can write values.Any() instead of values.Length != 0 and values.First() instead of values[0] also this new string[] { inp[0] } could be turned into values.Take(1).ToArray()
don't use abbreviations for variables like inp or f, use full names like values and predicate


x

public static string[][] CombineBy(this string[] values, Func&lt;string, bool&gt; predicate)
{
    var result = new List&lt;string[]&gt;();
    while (values.Any())
    {
        if (predicate(values.First()))
        {
            result.Add(values.Take(1).ToArray());
            values = values.Skip(1).ToArray();
        }
        else
        {
            var toAdd = values.TakeWhile(n =&gt; !predicate(n)).ToArray();
            result .Add(toAdd);
            values = values.Skip(toAdd.Length).ToArray();
        }
    }
    return result.ToArray();
}




Unfortuantely your code doesn't seem to work and returns invalid results. This should do:

public static List&lt;List&lt;string&gt;&gt; CombineBy(this string[] values, Func&lt;string, bool&gt; predicate)
{
    var result = new List&lt;List&lt;string&gt;&gt;();

    foreach (var value in values)
    {
        if (predicate(value))
        {
            if (!result.Any() || !predicate(result.Last().Last()))
            {
                result.Add(new List&lt;string&gt;());
            }
            result.Last().Add(value);
        }
        else
        {
            result.Add(new List&lt;string&gt; { value });
        }
    }

    return result;
}


or even without loops:

public static List&lt;List&lt;string&gt;&gt; CombineBy3(this string[] values, Func&lt;string, bool&gt; predicate)
{
    var result = values.Aggregate(new List&lt;List&lt;string&gt;&gt;(), (current, next) =&gt;
    {
        if (predicate(next))
        {
            if (!current.Any() || !predicate(current.Last().Last()))
            {
                current.Add(new List&lt;string&gt;());
            }
            current.Last().Add(next);
        }
        else
        {
            current.Add(new List&lt;string&gt; { next });
        }
        return current;
    });
    return result;
}