什么是基于LINQ的函数,它将所有满足谓词的项放在序列的前面,比如C ++' std::partition
?
答案 0 :(得分:4)
如果我理解你想要实现的目标,那么更简单的解决方案就是OrderByDescending
:
IEnumerable<T> Partition<T>(IEnumerable<T> s, Func<T, bool> predicate)
{
return s.OrderByDescending(predicate);
}
这是有效的,因为bool
在false
之前实现了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);
}