2012-11-16 114 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();