2011-02-25 20 views
8

Dizelerim var ve bu dizeler sayı ve sözcük içeriyor. Yapmak istediğim neLinq - Rakamlarla ve sayılarla sipariş ver

burada ... kelimelerin ardından sayılarla kararıyla şart (sayısal emir) (alfabetik sıraya göre)

Listem ikisinin bir karışımını içermez olan bir örnek

olduğunu > 1, 5, 400, 500, LT, RT

İşte

sahip olduğumun bir örnektir, bu ancak işler -

1, 5, 500, LT, RT, 400 -> LINQ Yazmanın daha iyi bir yolu olup olmadığını merak ediyordum?

  int results = 0; 
      // Grabs all voltages 
      var voltage = ActiveRecordLinq.AsQueryable<Equipment>() 
       .OrderBy(x => x.Voltage) 
       .Select(x => x.Voltage) 
       .Distinct() 
       .ToList(); 
      // Order by numeric 
      var numberVoltage = voltage 
       .Where(x => int.TryParse(x, out results)) 
       .OrderBy(x => Convert.ToInt32(x)); 
      // Then by alpha 
      var letterVoltage = voltage 
       .Where(x=> !String.IsNullOrEmpty(x)) 
       .Where(x => !int.TryParse(x, out results)) 
       .OrderBy(x => x); 

      return numberVoltage.Union(letterVoltage) 

Yardımın için teşekkürler!

+0

Neden ayrıştırma yaparsınız, voltaj bir int olarak tanımlanmamış mı? – Jimmy

+0

@Jimmy - Nope, voltaj int olarak tanımlanmamıştır çünkü bu, bazı durumlarda "LT" kelimesini içerir. Veritabanında dize olarak tanımlanmış – ChickSentMeHighE

cevap

17

(bir ToList telefonun var gibi) ben sadece özel bir karşılaştırıcısı kullanmak düşünüyorum işlem içi hepsini yapıyoruz Verilen: gibi

return ActiveRecordLinq.AsQueryable<Equipment>() 
         .Select(x => x.Voltage) 
         .Distinct() 
         .AsEnumerable() // Do the rest in-process 
         .Where(x => !string.IsNullOrEmpty(x)) 
         .OrderBy(x => x, new AlphaNumericComparer()) 
         .ToList(); 

AlphaNumericComparerIComparer<string> uygulayan bir şey Bu:

public int Compare(string first, string second) 
{ 
    // For simplicity, let's assume neither is null :) 

    int firstNumber, secondNumber; 
    bool firstIsNumber = int.TryParse(first, out firstNumber); 
    bool secondIsNumber = int.TryParse(second, out secondNumber); 

    return firstIsNumber 
     ? secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1; 
     : secondIsNumber ? 1 : first.CompareTo(second); 
} 
:

public int Compare(string first, string second) 
{ 
    // For simplicity, let's assume neither is null :) 

    int firstNumber, secondNumber; 
    bool firstIsNumber = int.TryParse(first, out firstNumber); 
    bool secondIsNumber = int.TryParse(second, out secondNumber); 

    if (firstIsNumber) 
    { 
     // If they're both numbers, compare them; otherwise first comes first 
     return secondIsNumber ? firstNumber.CompareTo(secondNumber) : -1; 
    } 
    // If second is a number, that should come first; otherwise compare 
    // as strings 
    return secondIsNumber ? 1 : first.CompareTo(second); 
} 

Sen ikinci bölümü için dev bir koşullu kullanabilirsiniz

... ama bu durumda sanmıyorum sanırım :)

+0

İşleri harika! Teşekkürler! – ChickSentMeHighE

6

Bu çözüm, her değer için bir kez ayrıştırma girişiminde bulunur.

List<string> voltage = new List<string>() { "1", "5", "500" , "LT", "RT", "400" }; 

List<string> result = voltage 
    .OrderBy(s => 
    { 
    int i = 0; 
    return int.TryParse(s, out i) ? i : int.MaxValue; 
    }) 
    .ThenBy(s => s) 
    .ToList();