Question: I've to do a generic method `Classify<T>` that, given a sequence of elements of type `T` and an arbitrary number of predicates, returns an array of `n+1` lists (where `n` is the number of the predicates). More precisely, if the element satisfies the first predicate then it is added to the first list. If not, then if the element satisfies the second predicate it is added to the second list, etc. If none of the predicates can be applied to one element, then that element is added to the last list (the n+1 th).

I managed to do that with the following code. Is there any way to do it better, maybe with Linq?

```
public List<T>[] Classify<T>(IEnumerable<T> sequence, params Predicate<T>[] predicates)
{
    var result = new List<T>[predicates.Length+1];
    var counter = 0;    
    foreach (var elem in sequence)      
    {
        var valid = false;
        foreach (var predicate in predicates) 
        {
            if(result[counter]==null)
                result[counter] = new List<T>();
            if (predicate(elem) && valid==false)
            {
                var partition = result[counter];
                partition.Add(elem);
                valid = true;
            }
            counter++;
        }
        if (!valid)     
        {
            if (result[counter] == null)
                result[counter] = new List<T>();
            result[counter].Add(elem);
        }
        counter=0;
    }
    return result;
}

```

Answer: 
```
public List<T>[] Classify<T>(IEnumerable<T> sequence, params Predicate<T>[] predicates)
{
    var result = new List<T>[predicates.Length + 1];
    // It's clearer to create elements of the array explicitly
    for (int i = 0; i < result.Length; i++)
        result[i] = new List<T>();

    foreach (var elem in sequence)
    {
        var index = predicates.TakeWhile(p => !p(elem))
                              .Count();

        result[index].Add(elem);
    }
}

```

There is a few LINQ methods to get an index, f.e. `Select((i, e) => ...)`. If the list of unsatisfied elements was the first (0th), I would use `Select`. But since it is the last, `TakeWhile` gives the shorter code.
The Linq answers are readable (well maybe not Jon's :-) ) but they're all slower than the OP's original code. I started with the intention to write a semi-Linq solution that was readable, but faster than the original, however, Linq, and copying arrays,# is slow :-(

In the end, I found this, which is readable, about 10% faster, and more correct\*:

```
public List<T>[] Classify<T>(IEnumerable<T> sequence, params Predicate<T>[] predicates)
{
    var partitions = new List<T>[predicates.Length + 1];
    for (int i = 0; i < partitions.Length; i++)
    {
        partitions[i] = new List<T>();
    }
    foreach (var elem in sequence)
    {
        var notfound = true;
        for (var i = 0; i < predicates.Length; i++)
        {
            if (predicates[i](elem))
            {
                partitions[i].Add(elem);
                notfound = false;
                break;
            }
        }
        if (notfound)
        {
            partitions[predicates.Length].Add(elem);
        }
    }
    return partitions;
}

```

#I attempted to add a "sentinel" predicate of `(e) => true` or even just `null`, but copying the existing `predicates` array, either to a `List` or to an array with one more element kills performance.

\*The bug fixed is the one addressed by creating the elements of the array explicitly: the OP code fails to return an array of empty lists when supplied an empty `sequence`.

Note that if the OP's intention was to call all the `predicates` on each element of `sequence` as the current code does, dropping the `break;` and adding `&& notfound` to the `if` will make it identical in behaviour.