2017-06-02 9 views
1

私と一緒にいて、私はこれをあまりにも複雑にしないようにします。私は製品のリストを持っています。製品は次のようになります。C#複数の条件で並べ替える

{ 
    "id": 3797, 
    "title": "Canon EOS 100D Digital SLR Camera with 18-55 IS STM Lens, HD 1080p, 18MP, 3\" LCD Touch Screen", 
    "shortTitle": "Canon EOS 100D Black", 
    "brand": "Canon", 
    "model": "EOS 100D", 
    "colour": "Black", 
    "gtin": "8714574602721", 
    "image": "http://piiick.blob.core.windows.net/images/Canon-EOS-100D-18-55-Black-8714574602721.png", 
    "type": "Digital SLR", 
    "lensFocalLength": "18-55", 
    "lensType": "IS STM", 
    "lensMount": "EF/EF-S", 
    "maxAperture": "999", 
    "connectivity": "", 
    "shootingModes": "Scene Intelligent Auto (Stills and Movie), No Flash, Creative Auto, Portrait, Landscape, Close-up, Sports, SCN(Kids, Food, Candlelight, Night Portrait, Handheld Night Scene, HDR Backlight Control), Program AE , Shutter priority AE, Aperture priority AE, Manual (Stills and Movie)", 
    "weight": 410.0, 
    "width": 116.8, 
    "height": 90.7, 
    "depth": 69.4, 
    "digitalZoom": "N/A", 
    "opticalZoom": "N/A", 
    "waterproof": false, 
    "maxVideoResolution": "1920 x 1080", 
    "sensorType": "CMOS", 
    "sensorSize": "22.3 x 14.9 mm", 
    "continuousShootingSpeed": "4", 
    "iso": "1600", 
    "style": "traditional", 
    "designer": "", 
    "dateAnnounced": "10/06/2008", 
    "focusPoints": 7 
} 

しかし、これを簡単に説明します。 複数の列を並べ替えるソート方法を作成しようとしています。

/// <summary> 
/// Performs an advanced sort on products using sortations 
/// </summary> 
/// <param name="products">The products to sort</param> 
/// <param name="sortations">The sortation list</param> 
public void AdvancedSort(List<JObject> products, List<Sortation> sortations) 
{ 

    // Get our value types 
    GetTypesFromOperator(sortations); 

    // Sort our products by the sortations 
    products.Sort((a, b) => 
    { 
     foreach (var sortation in sortations) 
     { 

      // Get our values 
      var fieldName = sortation.Field; 
      var x = a.SelectToken(fieldName).ToString(); 
      var y = b.SelectToken(fieldName).ToString(); 
      var type = sortation.Type; 

      // If both values are the same, skip the rest of this iteration 
      if (x.Equals(y)) return 0; 

      // If we have an expression 
      if (!string.IsNullOrEmpty(sortation.Expression)) 
      { 

       // If we are checking for between 
       if (sortation.Operator == "><") 
       { 

        // Get our values 
        var values = sortation.Expression.Split(','); 

        // If we have 2 values 
        if (values.Length == 2) 
         return CompareBetween(values, x, y); 
       } 

       // If we are checking booleans 
       if (sortation.Operator == "===") 
        return CompareBoolean(sortation.Expression); 

       // If we are checking equals 
       if (sortation.Operator == "=") 
        return y.Equals(sortation.Expression) ? 1 : -1; 

       // If we are checking like 
       if (sortation.Operator == "%") 
        return y.Equals(sortation.Expression, StringComparison.OrdinalIgnoreCase) ? 1 : -1; 
      } 

      // If we get this far, do a switch on sortation types 
      switch (sortation.Type) 
      { 
       case SortationValueType.Boolean: 
        return Boolean.Parse(x) ? -1 : 1; 
       case SortationValueType.Number: 
        return CompareNumeric(x, y, sortation.Direction); 
       default: 
        return string.CompareOrdinal(x, y); 
      } 
     } 

     // If nothing matches, return 0 
     return 0; 
    }); 
} 

プロパティ値のタイプに基づいて並べ替えしようとしていると私はsortations呼び出す: は例えば、私はこの方法を持っています。 ソートは、演算子、式、および照会するフィールドを規定した単なるクラスです。 これは仕分けの例です。今、私たちは動的に追加されている異なるsortationsの数を持つことができます

// Add importance, expert and sponsored 
sortations.Add(new Sortation 
{ 
    Field = "importance", 
    Operator = "<" 
}); 

。私はこれらの分類によって製品を分類できる必要があります。 私は簡単なテスト作成しました:私はこの出力を得るであろうと、それに期待

[Test] 
public void SortBySilverColourSilverShouldBeTop() 
{ 

    // Assemble 
    var json = "[{ colour: 'Black', importance: '150' }, { colour: 'Black', importance: '150' }, { colour: 'Black', importance: '150' }, { colour: 'Silver', importance: '150' }, { colour: 'Black', importance: '149' }, { colour: 'Black', importance: '149' }, { colour: 'Black', importance: '149' }, { colour: 'Silver', importance: '149' }]"; 
    var products = JsonConvert.DeserializeObject<List<JObject>>(json); 
    var sortations = new List<Sortation>() { new Sortation() { Field = "colour", Operator = "=", Expression = "Silver" }, new Sortation() { Field = "importance", Operator = "<" } }; 

    // Act 
    _sortProvider.AdvancedSort(products, sortations); 
    var result = products[0].SelectToken("colour").ToString(); 

    // Assert 
    Assert.That(result, Is.EqualTo("Silver")); 
} 

を:

[ 
    { colour:'Silver', Importance:'150'}, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Silver', Importance:'149' }, 
    { colour:'Black', Importance:'149' }, 
    { colour:'Black', Importance:'149' }, 
    { colour:'Black', Importance:'149' } 
] 

を代わりに、私はこの出力を得る:

[ 
    { colour:'Silver', Importance:'150' }, 
    { colour:'Silver', Importance:'149' }, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Black', Importance:'150' }, 
    { colour:'Black', Importance:'149' }, 
    { colour:'Black', Importance:'149' }, 
    { colour:'Black', Importance:'149' } 
] 

缶誰かが私のソート方法を修正するのに役立つ?

+0

この種のものは、データがある種のデータベースに入っているときには本当に簡単です。その事実の後で手動でソートするよりも、パフォーマンスが向上します。このデータが最初にデータベースから取得されたものであれば、ソートをクエリの一部に変換するほうがはるかに良いでしょう。それがデータベースから来ていない場合、それをデータベースに入れることを検討するかもしれません。 – ashbygeek

+0

それはAPIから来て、なぜそれがjsonにあるのですか?D – r3plica

答えて

2

ごsortationsの順序を交換してみてくださいソートはまったく重要ではありません。これは時間がかかりますが、それぞれの仕分けを考える

// Get our value types 
GetTypesFromOperator(sortations); 

foreach (var sortation in sortations) 
{ 
    // Sort our products by the sortations 
    products.Sort((a, b) => 
    { 
     // Get our values 
     var fieldName = sortation.Field; 
     var x = a.SelectToken(fieldName).ToString(); 
     var y = b.SelectToken(fieldName).ToString(); 
     var type = sortation.Type; 
     .... 
     .... 
    } 
} 

:私は何をする必要がそうのようなforeachのとproducts.sort呼び出し、スワップであると考えています。リストの最後のソートが最も重要であることに注意してください。

+0

もっと遅く話していると思いますか?私は決して200以上の製品を持っていないでしょうし、おそらく3つ以上の並べ替えを持っていることはありません – r3plica

+0

これらのサイズでは、あなたを悩ますほど遅くはありません。余分な並べ替えは、最も効率的な並べ替えアルゴリズムでも多くの計算量を必要とするため、最大の問題を引き起こしますが、最大で3つは元の数よりもわずか3倍長くなると予想できます。 – ashbygeek

1

あなたはそれらを後方に持っているように見えます - それはすべての "シルバー"を最初に置き、重要度順に2番目に並べます。あなたの基本的な問題は、最初の仕分けが試合を打つとすぐとして、それはソート関数にソート順序値との残りの部分を返すことである私の心の中で

var sortations = new List<Sortation>() { 
    new Sortation() { Field = "importance", Operator = "<" }, 
    new Sortation() { Field = "colour", Operator = "=", Expression = "Silver" } 
}; 
+0

私がそれを行うと、「Silver」製品は各重要ブロックの最後に終わります – r3plica

+0

実際には、それは決して2番目のソートの – r3plica

関連する問題