2014-06-24 86 views

回答

4

如果我理解你想達到什麼樣的,一個簡單的解決方案將是OrderByDescending

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

這工作,因爲bool實現IComparable<bool>false來臨前true。因此predicate評估爲true的項目將首先放置在結果集中。

這裏是一個手工製作的實現,以防萬一您感興趣。我沒有做任何基準測試,但這個測試可能會更快。

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(Ñ),但OrderBy被認爲是O(Ñ日誌Ñ)。但是,根據OrderBy方法的實施細節,它們可能執行幾乎完全相同。

+1

一個次要的事情是,由馬特·克萊恩提供的嘗試評估熱切而'OrderByDescending'將推遲。我肯定會贊成'OrderByDescending'解決方案,但只要馬特知道與他的實現有所不同就可以了。 –

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()); 
} 
0

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

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

這將組合這些項目,但它不會以任何保證順序返回組 - 如果第一項評估爲true,它將返回所有true的第一個,如果它評估爲false,它將返回所有false的第一。你仍然需要某種'OrderBy'。 –

+0

@ p.s.w.g謝謝。那麼,這只是你的一個複雜版本。 – Lumen