2009-04-28 5 views
0

私はオブジェクトのコレクションを持っていて、それらを2つのリストに分ける方法が不思議です - 1つのリストにはすべて特定のタイプのものがあり、残り。私はそれをやって考える一つの方法は次のとおりです。プロパティ値に基づいてオブジェクトを別々のリストに入れるのが最も簡単な方法

var typeXs = (from o in collectionOfThings where o.Type == "typeX" select o); 
var notTypeXs = (from o in collectionOfThings where o.Type != "typeX" select o); 

他の方法はcollectionOfThings上だけループすること及び/他の場合に基づき割り当てます。

どちらの方法もシンプルで読みやすいですが、奇妙な方法がありますか?

答えて

4

(補正)後:

class MyObject 
{ 
    public int n; 
    public string t; 
} 

ロードまで、私の元のリスト:

List<MyObject> allObjects = new List<MyObject>() { 
    new MyObject() { n = 0, t = "x" }, 
    new MyObject() { n = 1, t = "y" }, 
    new MyObject() { n = 2, t = "x" }, 
    new MyObject() { n = 3, t = "y" }, 
    new MyObject() { n = 4, t = "x" } 
}; 

スプリットアウト使っ種類:

var typeXs = allObjects.FindAll(i => i.t == "x"); 
var notTypeXs = allObjects.FindAll(i => i.t != "x"); 

それとも

var typeXs = allObjects.Where(i => i.t == "x").ToList<MyObject>(); 
var notTypeXs = allObjects.Except(typeXs).ToList<MyObject>(); 
また

は、他の2つのオプションをアウトパフォームする必要がありますが、理論的にを一度、したがって、唯一の繰り返し処理List.ForEachメソッドを使用することができます。また、LINQライブラリを参照する必要もありません。つまり、.NET 2.0で安全です。

var typeXs = new List<MyObject>(); 
var notTypeXs = new List<MyObject>(); 
allObjects.ForEach(i => (i.t == "x" ? typeXs : notTypeXs).Add(i)); 
+0

2番目の例は、おそらく最高ですが、すべてのオプションを与える良い仕事です。 +1 – BobTheBuilder

+1

私は実際にはそれが2.0の安全であるという事実のために最後の例を実際に好む... – BenAlabaster

+1

それはコレクションを1回だけ繰り返すだけで、他のオプションは両方ともコレクションを2回反復する必要があります少しエレガントに書かれています。 – BenAlabaster

0
coll.GroupBy(o => o.Type == "TypeX"); 
+0

IEnumerable >を返すとどうなるのかよく分かりません – JeremyWeir

1

あなたは、私はすべてのあなたの上にejoptimilateする必要はありませんが、私はあなたが一度だけ反復検討すべきだと思います

var notTypeXs = collectionOfThings.Except(typeXs); 
+0

これは最もクリーンで表現力豊かな方法です。 –

0

ように、第2の部分を書き換えることができます。

// You can optimize this by specifying reasonable initial capacities. 
List<TypedO> typeXs = new List<TypedO>(); 
List<TypedO> notTypeXs = new List<TypedO>(); 

foreach(TypedO o in list) 
{ 
    (o.Type == "typeX" ? typeXs : notTypeXs).Add(o); // Yeah, I know. 
} 

この例では、あなたがしているものを示すべき

+0

ありがとう、私はそれを考えていた: "もう一つの方法は、collectionOfThingsをループし、if/elseに基づいて割り当てることです。" – JeremyWeir

+0

私が冗長だったら申し訳ありません。私はちょうどこのオプションを推奨しなければならず、厳密に言えば、ifまたはelseを使用しませんでした。:) –

0

あなたは、その後、二回リストスルー行きたくない場合は、次の

var collectionOfThings = new[] 
     { 
      new Thing { Id = 1, Type = "typeX" }, 
      new Thing { Id = 2, Type = "typeY" }, 
      new Thing { Id = 3, Type = "typeZ" }, 
      new Thing { Id = 4, Type = "typeX" } 
     }; 


    var query = (from thing in collectionOfThings 
       group thing by thing.Type == "typeX" into grouped 
       //orderby grouped.Key descending 
       select new 
       { 
        IsTypeX = grouped.Key, 
        Items = grouped.ToList() 
       }).ToList(); 

    var typeXs = query.Find(x => x.IsTypeX).Items; 
    var notTypeXs = query.Find(x => !x.IsTypeX).Items; 
0

私はこれらの線に沿って、 'OfType' リンク式を使用します。

var typeXs = collectionOfThigs.OfType<typeX>(); 
var notTypeXs = collectionOfThings.Except(typeXs); 

(他の回答を除いて。)。これはあなたがタイプ文字列だけでなくタイプを持っていると仮定します。

また、決定を一度しないとパフォーマンスが低下する可能性があります(スプリット追加が問題の場合は、おそらく行く方法です)が、パフォーマンスが問題でない限り、明快さが私の好みです。