2016-09-19 8 views
-1

私はDescription性を有し、3 productオブジェクトを持つproductクラスを持っている:いくつかのプロパティに基づいてクラスオブジェクトをグループ化して順序付けしますか?

Product product1 = new Product("This is bottom product"); 
Product product2 = new Product("This is top product"); 
Product product3 = new Product("This is medium product"); 

List<Product> lst = new List<Product>(); 
lst.Add(product1); 
lst.Add(product2); 
lst.Add(product3); 

私は一番下に来るtopdescriptionを持つすべてのproductsbottomとしてdescriptionでトップとproductに来るように、これらのオブジェクトを再アレンジしたいです。

var res = lst.Where(p => p.Desription == "This is top product") 
         .Concat(lst.Where(p => p.Desription == "This is medium product")) 
         .Concat(lst.Where(p => p.Desription == "This is bottom product")).ToList(); 

これを達成するために上記のクエリをコーディングしました。これは私に正しい結果を返します。しかし、これがこの問題を解決する最も効率的な方法であるかどうかはわかりません。

誰かが代替/パフォーマンスに優れたアプローチを提案できますか?

注:ここでは問題を簡略化しました。それ以外の場合、製品にはさらに多くのオブジェクトとプロパティがあります。

+2

? – AVK

+0

私が持っているロジックはまだ動作しますが、遅くなると思います。 – maverick

+4

問題を完全に変更するのは悪い形式です(別名カメレオン問題)。あなたの編集内容は、誰もが間違っていたのではなく、根本的に問題を変えたので、皆の答えを無効にしています。 – Igor

答えて

2

編集:比較演算(速く)より

よりよい解決策:

public enum ProductType 
    { 
     Bottom=0, 
     Medium, 
     Top, 
    } 

    public class Product 
    { 
     public ProductType Type { get; set; } 
     //the rest of properties here 
    } 

var list = new List<Product>(); 
var orderedList = list.OrderBy(x => (int)x.Type).ToList(); 

あなたは、既存のクラスに何も追加多分それをラップしたり拡張したくない場合は?

+0

です@FirstStepここでは – MistyK

+0

です。 – maverick

+0

ニースの解決策、+1 –

0

は、ヘルパーDictionaryを使用します。

Dictionary<string, int> myDic = new Dictionary<string, int> 
{ 
    {"top", 1}, 
    {"medium", 2}, 
    {"bottom", 3} 
}; 
var res = lst.OrderBy(c => myDic[c.Desription.Split(' ')[2]]); 
+0

editted問題。 – maverick

0

次のオプションを試すことができます。

オプション1:(なしの中間構造/加工必要)

IEnumerable<Product> finalResult = lst.GroupBy(p => p.Description) 
             .OrderByDescending(g => g.Key) 
             .SelectMany(g => g.Select(p => p)); 

オプション2 :(中間構造の登録)

var groupedList = lst.GroupBy(p => p.Desription) 
  • 中間リスト

    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Top"); 
    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Medium"); 
    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Bottom"); 
    
  • 選択に関連する要素を追加した説明では

    var intermediateResult = new List<IGrouping<string,Product>>(); 
    
  • グループ:

    • 中間結果を保持するためのリストを作成します。一覧あなたの質問でこれを考えると

      IEnumerable<Product> finalResult = intermediateResult.SelectMany(g => g.Select(p => p)); 
      
  • +0

    中間リストは必要ありません。 –

    +0

    @Ivan Stoev合意しました。私は 'OrderBy'を使用する必要がありますが、これは単なる例であり、実際のデータが異なる可能性があるため、OPのどのような辞書順 –

    1

    を平坦化を経由して最終的な結果:私は「

    var res = lst.OrderBy(p => p.Desription); 
    

    var res = lst.Where(p => p.Desription == "This is top product") 
             .Concat(lst.Where(p => p.Desription == "This is medium product")) 
             .Concat(lst.Where(p => p.Desription == "This is bottom product")).ToList(); 
    

    私はあなたが探しているものと考えているが、このようなものです"Description"の変数のスペルが間違っていることを指摘したい。

    List<Product> res = new List<Product>(); 
    for (int i = 0; i < lst.Count(); i++) 
    { 
        res.AddRange(lst.Where(p => p.Desription.Contains("top").ToList()); 
        res.AddRange(lst.Where(p => p.Desription.Contains("medium").ToList()); 
        res.AddRange(lst.Where(p => p.Desription.Contains("bottom").ToList()); 
    } 
    

    は、私が代わりにAddRangeを使用する:あなたは、各説明は単に特定の文言「上部」、「ボトム」、「中」とそれらの一つだけが含まれています知っていれば

    0

    、このような何かを試してみてくださいAddの「トップ」、「ミディアム」または「ボトム」の製品が複数存在する可能性があるためです。あなたは100の製品を持っている場合はどう

    説明は「トップ」および「ボトム」同じ文で、「トップ」と「メディア」を含む場合にも、それは動作しません、など

    関連する問題