LINQ相当于std :: partition

时间:2014-06-24 21:26:36

标签: c# linq partitioning stl-algorithm

什么是基于LINQ的函数,它将所有满足谓词的项放在序列的前面,比如C ++' std::partition

3 个答案:

答案 0 :(得分:4)

如果我理解你想要实现的目标,那么更简单的解决方案就是OrderByDescending

IEnumerable<T> Partition<T>(IEnumerable<T> s, Func<T, bool> predicate)
{
    return s.OrderByDescending(predicate);
}

这是有效的,因为boolfalse之前实现了IComparable<bool> true。因此,predicate评估为true的项目将首先放在结果集中。

这是一个手工制作的实现,以防万一你感兴趣。我没有做过任何基准测试,但实际上这个基准测试可能更快。 1

IEnumerable<T> Partition<T>(IEnumerable<T> s, Func<T, bool> predicate)
{
    List<T> falses = new List<T>();
    foreach(var t in s) 
    {
        if (predicate(t)) 
        {
            yield return t;
        }
        else
        {
            falses.Add(t);
        }
    }

    foreach (var t in falses)
    {
        yield return t;
    }
}

1:手工制作的解决方案是O( n ),但OrderBy被认为是O( n log ñ)。但是,根据OrderBy方法的实现细节,它们可能几乎完全相同。

答案 1 :(得分:0)

我最好的一击:

IEnumerable<T> Partition<T>(IEnumerable<T> s, Func<T, bool> predicate)
{
    var split = s.GroupBy(predicate);
    return split
        .Where(kv => kv.Key)
        .Single()
        .Concat(split
            .Where(kv => !kv.Key)
            .Single());
}

答案 2 :(得分:0)

使用SelectMany,您可以改善自己的答案:

IEnumerable<T> Partition<T>(IEnumerable<T> s, Func<T, bool> predicate)
{
    return s.GroupBy(predicate).SelectMany(xs => xs);
}