2012-11-16 45 views
5

我想知道如何可以排序字符串[根據特定字符串的位置]的項排序的字符串數組。例如我想通過子串以下數組進行排序 「 - 」根據字符串的位置(C#)

輸入:{XX - C,XXXXX - B,YYY - 一個,mlllll - d}

預期輸出:{YYY - 一個, XXXXX - b,XX - C,mlllll - d}

我至今如下:

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(); 
    } 
} 

有人可以請給我一個提示...?

+0

它看起來像你想通過這封信後'-'來排序,不是由'-'的位置,這是一樣的在所有的字符串? – Esailija

+0

所以你想要的是字符串數組進行排序,只基於它的字符串的最後一部分?因此,例如忽略前4個字符? 「 - 」(或在你的情況,只是後面的部分?」 –

+0

OK對不起,我是不是specifing還不夠清楚,我想在那裏過一個給定的字符串X首次出現時字符串[]內的所有項目進行排序如果X沒有在項目Y存在,那麼就要把Y在新的String []的結束。 我現在希望它更清楚......? – oren

回答

3

爲了更好的性能和設計,我建議你使用方法:

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; 
     } 

    } 

您也可以刪除SortByStringPos方式,並從你的代碼的任何地方撥打Array.Sort(arr, new MyStrComparer("-", ascending));

+0

嗯......這段代碼的結果是不正確的 – oren

+0

@oren只是編輯,我認爲現在 – LMB

+0

System.ArgumentOutOfRangeException ... – oren

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

我猜

,所以你需要將它訂購通常的方式,那麼你可以使用這個,像ORDERBY .... thenBy

+0

不起作用:-( – oren

+0

你能解釋一下更具體你想達到什麼 – 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

當輸入中的字符串X不攜帶定界符它,它就會迷路......不好:-( – oren

+0

固定情況下丟失的分隔符:) – maximpa

+0

大,似乎是解決方案,謝謝馬克西姆! – oren

0

使用Substring獲取字符串的最後部分。 LINQ查詢可以逐步構建。這減少了代碼的重複(= DRY原則,不重複自己):

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();