2013-03-07 12 views
61

私はこのようないくつかの識別子のリストを持っています。ソート別のリストIDからリストは

List<T> docs = GetDocsFromDb(...) 

私はList<T>内の項目は、(エンジン得点の理由を検索することにより)最初の1に比べて同じ位置になければならないように、両方のコレクションで同じ順序を維持する必要があります。そして、このプロセスはGetDocsFromDb()機能では実行できません。

必要に応じて、2番目のリストを他の構造(たとえばDictionary<long, T>)に変更することはできますが、変更しないことをお勧めします。

は、LINQで、この「いくつかのIDに応じて、ordenation」を行うための任意の単純かつ効率的な方法はありますか?あなたは

IEnumerable<T> OrderBySequence<T, TId>(
     this IEnumerable<T> source, 
     IEnumerable<TId> order, 
     Func<T, TId> idSelector) 
{ 
    var lookup = source.ToDictionary(idSelector, t => t); 
    foreach (var id in order) 
    { 
     yield return lookup[id]; 
    } 
} 

が何をしたいのための一般的な拡張である、Tを指定していないので

List<T> docs = GetDocsFromDb(...).Zip(docIds, Tuple.Create) 
       .OrderBy(x => x.Item2).Select(x => x.Item1).ToList(); 
+0

あなたはすべての 'docId'がdocs''に一度だけ発生することを保証され、どのようなプロパティが 'Id'またはセレクタ' funcが '必要になりますを開催しますか! – Jodrell

+0

最初のリストは「マスターリスト」を表していますか?別の言葉では、第2のリストは、第1のリストの一部(または全体)を表すサブセットであろうか? – code4life

答えて

170
docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList(); 
+0

@ Kaf thatsなぜ私はupvotedも、ドキュメントIDプロパティが 'Id'と呼ばれていることに頼っています。その質問には指定されていません。 – Jodrell

+0

@BorjaLópez、速報。あなたはあなたの質問に効率性を言及します。 'IndexOf'はあなたの例ではとても受け入れがたい素敵でシンプルです。あなたが多くのデータを持っていたなら、私の答えはより適切かもしれません。 http://stackoverflow.com/questions/3663014/why-is-this-list-indexof-code-so-much-faster-than-the-listi-and-manual-compa – Jodrell

+0

私はこの方法をベンチマークとしました1つはディクショナリ(以下を参照)で、それはほぼ2倍の速さです。 –

-1

一つの簡単な方法は、順序付けシーケンスをzip圧縮することです。

あなたはより安全なバージョンがsourceorderと正確にジップいない場合は動作します

IEnumerable<T> OrderBySequence<T, TId>(
     this IEnumerable<T> source, 
     IEnumerable<TId> order, 
     Func<T, TId> idSelector) 
{ 
    var lookup = source.ToLookup(idSelector, t => t); 
    foreach (var id in order) 
    { 
     foreach (var t in lookup[id]) 
     { 
      yield return t; 
     } 
    } 
} 

かもしれません

var orderDocs = docs.OrderBySequence(docIds, doc => doc.Id); 

、おそらくこのような拡張機能を使用することができます。

+0

なぜジップ後に注文しますか? – Jodrell

+0

'Zip'は各インデックスを(タプルに)対応するリスト内の同じ位置にあるドキュメントと組み合わせるためです。次にOrderByはTuplesをインデックス部分でソートし、次にselectは現在の順序リストからドキュメントを掘り下げます。 –

+0

しかし、GetDocsFromDbの結果には順序がありませんので、 'Item1'が' Item2'と無関係なタプルを作成します。 – Jodrell

関連する問題