2012-11-16 3 views
5

Belirli bir dize konumuna göre bir dizginin [] öğelerini nasıl sıralayabileceğimi bilmek isterim. {Xx - C, XXXXX - b, yyy - a, mlllll - b}Bir dize dizisini bir dize konumuna göre sıralama (C#)

Beklenen çıkış: - ""

giriş Örneğin I altkatarıyla aşağıdaki diziyi sıralamak istediğiniz {yyy - a, xxxxx - b xx - mlllll c - d}

ne ben şimdiye kadar sahip şudur:

public string[] SortByStringPos(string[] arr, string str, bool ascending) 
{ 
    if (ascending) 
    { 
     var result = from s in arr 
        where s.Length >= s.IndexOf(str) 
        orderby s[s.IndexOf(str)] ascending 
        select s; 

     return result.ToArray(); 
    } 
    else 
    { 
     var result = from s in arr 
        where s.Length >= s.IndexOf(str) 
        orderby s[s.IndexOf(str)] descending 
        select s; 

     return result.ToArray(); 
    } 
} 

birisi bana bir ipucu bırakır mısın ...?

+0

sen -' 'sonra gelen harfin göre sıralamak istiyorum gibi değil, aynı -'' konumuyla görünüyor tüm dizelerde? – Esailija

+0

İstediğiniz, dizenin yalnızca son kısmına göre sıralanmış dizge dizisidir. Yani ilk 4 karakteri görmezden mi geliyorsun? (Ya da sizin durumunuzda, sadece - "-"? " –

+0

'un arkasındaki bölüm. Üzgünüm, yeterince açıklamıyordum. Dizgideki [] herhangi bir dizginin ilk defa meydana geldiği [/] dizisindeki tüm öğeleri sıralamak istiyorum Eğer X bir öğede X bulunmuyorsa, o zaman sadece yeni dizgenin sonuna [Y] koyun. Şimdi umarım artık daha açık ...? – oren

cevap

3

böylece o zaman orderBy gibi kullanabilir, her zamanki gibi sipariş gerekiyor galiba, seni tavsiye kullanın: Ayrıca SortByStringPos yöntemini silmek ve her yerde kodunuzu gelen Array.Sort(arr, new MyStrComparer("-", ascending)); çağırabilir

public void SortByStringPos(string[] arr, string str, bool ascending) 
    { 
     Array.Sort(arr, new MyStrComparer("-", ascending)); 
    } 

    class MyStrComparer : Comparer<string> 
    { 
     string delimiter; 
     bool isAscending; 

     public MyStrComparer(string aStr, bool ascending) 
     { 
      delimiter = aStr; 
      isAscending = ascending; 
     } 

     public override int Compare(string x, string y) 
     { 
      var r = GetMySubstring(x).CompareTo(GetMySubstring(y)); 
      return isAscending ? r : -r; 
     } 

     string GetMySubstring(string str) 
     { 
      return str.IndexOf(delimiter) != -1 ? str.Substring(str.LastIndexOf(delimiter)) : string.Empty; 
     } 

    } 

.

+0

hmmm elde etmeye çalışıyorsunuz ... bu snippet'in sonucu doğru değildi – oren

+0

@oren Sadece düzenlenmiş. Sanırım şu anda – LMB

+0

System.ArgumentOutOfOangeException ... – oren

3
orderby x=>x.Substring(x.LastIndexOf('-')) 

i .... daha iyi bir performans ve tasarım için ThenBy

+0

çalışmıyor :-( – oren

+0

daha spesifik olarak – m4ngl3r

2
static void Main() 
{ 
    var input = new[] { "xx - c", "xx - b", "yy - a", "ml - d", }; 
    var delimeter = "-"; 
    var isAscending = true; 

    var res = Sort(input, delimeter, isAscending); 
} 

static string[] Sort(string[] input, string delimeter, bool isAscending) 
{ 
    var withDelimeter = input.Where(p => p.Contains(delimeter)); 
    var withoutDelimeter = input.Except(withDelimeter); 

    Func<string, string> selector = p => p.Substring(p.IndexOf(delimeter)); 

    return 
     (
      isAscending 

       ? withDelimeter.OrderBy(selector) 
        .Concat(withoutDelimeter.OrderBy(p => p)) 

       : withoutDelimeter.OrderByDescending(p => p) 
        .Concat(withDelimeter.OrderByDescending(selector)) 
     ) 
     .ToArray(); 
} 
+0

Girdi içindeki bir dize, içinde ayraç taşımazsa, kaybolur ... kötü :-( – oren

+0

Eksik sınırlayıcılar için sabit durum :) – maximpa

+0

Harika, çözüm gibi görünüyor, teşekkürler Maxim! – oren

0

Dizenin son bölümünü almak için Substring kullanın. LINQ sorguları adım adım oluşturulabilir. Bu kod tekrarları (= KURU ilkesi, Do not tekrar) azaltır:

var query = arr.Where(s => s.Contains(str)); 
Func<string,string> sortExpr = s => s.Substring(s.IndexOf(str)); 
if (ascending) { 
    query = query.OrderBy(sortExpr); 
} else { 
    query = query.OrderByDescending(sortExpr); 
} 
return query.ToArray();