2012-12-03 3 views
1

나는이 글에 많은 글을 올렸지 만 내 경우와 일치시키지 못했습니다.문자열을 하이픈으로 비교하기

은 내가 내 출력 100-1, 100-11, 100-20, 100-3

입니다 this location

void Main() 
{ 
    string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" }; 

    foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer())) 
    {  
     Console.WriteLine(thing); 
    } 
} 

public class SemiNumericComparer: IComparer<string> 
{ 
    public int Compare(string s1, string s2) 
    { 
     if (IsNumeric(s1) && IsNumeric(s2)) 
     { 
      if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1; 
      if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1; 
      if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0; 
     } 

     if (IsNumeric(s1) && !IsNumeric(s2)) 
      return -1; 

     if (!IsNumeric(s1) && IsNumeric(s2)) 
      return 1; 

     return string.Compare(s1, s2, true); 
    } 

    public static bool IsNumeric(object value) 
    { 
     try { 
      int i = Convert.ToInt32(value.ToString()); 
      return true; 
     } 
     catch (FormatException) { 
      return false; 
     } 
    } 
} 

에서 선택되는 정렬하는 코드를 다음 사용

List<string> list = new List<string>{ "100-1", "100-11", "100-3", "100-20" }

목록에서 일부 문자열을 나는 믿는다 -decimal으로 설정하고 값을 비교하십시오. 사실 나는 결과가 100-1, 100-3, 100-11, 100-20 일 것으로 예상하고있었습니다. 방금 ​​실제로 어떤 기준으로 정렬을 수행했는지 알고 싶었습니다. 어떤 도움을 주셔서 감사합니다. 심지어 나는 100-2100-20을 다르게 취급 할 것으로 기대합니다.

즉석에서 필자는 Infragistic 컨트롤 그리드에서 정렬을하면 여기에 예상했던 결과와 동일한 결과가 나타납니다. 나는이 목록에있는 다른 많은 문자열 값이

편집, 일부는 등등 정수, 복식이다. 하이픈은 여기서 언급 한 것입니다.

+1

하는 경우 (대시없이) 목록 _were_ 수의 일부 요소는 그들 각각 두 번'Convert.ToInt32'을 부를 것이다. 그리고'try'-'catch '를 사용하는 것이 최선의 방법은 아닙니다. 대신 int.TryParse 메소드를 확인하십시오. 숫자인지 아닌지 확인하고, 한 번에 숫자를 알려줍니다. 그리고 예외를 잡을 필요가 없습니다. 그리고 "좋은"정수가되기 위해서's1'과's2'가 따라야 할 몇 가지 "숫자 스타일"을 지정할 수 있습니다. –

+0

문자열로 정렬합니다. 상상해보십시오 문자가있는 숫자 : 1 => a; 3 => c; 11 => aa. 그렇다면 그것은 a, aa, c, a, c, aa로 분류 될 것입니다. 원하는 결과를 얻으려면 비교 자의 특수한 경우로 하이픈 또는 다른 구분 기호로 문자열을 처리해야합니다. – juharr

+0

도움을 주셔서 감사합니다 – Sandy

답변

1

두 번째 숫자 (하이픈 다음)로 항목을 정렬하려면 문자열을 숫자로 분석 한 다음이를 사용하여 순서를 매겨 야합니다. 당신은 시도 할 수 있습니다 :

string[] things = new string[] { "100-1", "100-11", "100-3", "100-20" }; 
var test = things.OrderBy(r => int.Parse(r.Split('-')[1])).ToArray(); 

현재 코드가 작동하지 않는 이유는 그것 때문에 정수 값으로 문자열 100-을 구문 분석 할 수 없습니다 및 함수 IsNumeric가 false를 반환된다는 사실에 아마. 예상대로이 작동합니다

+0

+1 ... 예 ... IsNumeric은 false를 반환합니다. 그러나 문자열을 값으로 사용하는 경우에도 어떤 기준으로이 출력을 내게 제공합니까 ?? 또한이 종류와 함께 많은 다른 종류의 문자열 (int, double 문자열)이 있다고 언급 한 편집 된 게시물을 참조하십시오. 이 bcoz 사용자가 하이픈과 별도로 특수 문자를 입력 할 수도 있습니까? – Sandy

+1

@rapsalands'123-45'는 숫자가 아니기 때문에 코드는 항상'string.Compare (s1, s2, true); '로 떨어집니다. 당신은 정상적인 문자열 ordeing을 받고있어. – Rawling

4
var sorted = things.Select(s => s.Split('-')) 
       .OrderBy(x => double.Parse(x[0])) 
       .ThenBy(x => double.Parse(x[1])) 
       .Select(x=>String.Join("-",x)) 
       .ToList(); 
+0

사용자가'-'보다는 다른 특수 문자를 가질 수 있기 때문에 가능할 것인가 ?? 그것의 다만 의심 : – Sandy

+0

Linq는 다만 차갑다. – Polyfun

+0

@rapsalands 당신의 도움을 받아 주셔서 감사합니다 ..... + 1 –

2

:

string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" }; 
IEnumerable<string> ordered = things 
      .Select(s => new 
      { 
       str = s, 
       firstPart = s.Split('-').ElementAtOrDefault(0), 
       secondPart = s.Split('-').ElementAtOrDefault(1) 
      }) 
      .OrderBy(x => int.Parse(x.firstPart)) 
      .ThenBy(x => int.Parse(x.firstPart)) 
      .Select(x => x.str); 

foreach (string s in ordered) 
    Console.WriteLine(s); 

는 데이터가 엄격한 것으로 간주하지만, 그렇지 않으면 당신은 int.Parse(x.firstPart)에서 예외 f.e에 열려있어.

데모 : http://ideone.com/UJ5Yt4

+0

그것은 가능한 것입니다 어떤 char's.Split (새 문자 [] - ','# '})' – Sandy

+0

@rapsalands : 당신은 여러 분리자를 사용하기 위해 [** this overload **] (http://msdn.microsoft.com/en-us/library/ms131448.aspx)를 사용할 수 있습니다. 그러나 입력이 임의적이라면 분리를 사용할 수 없습니다. 하지만 뭔가 잘못되고 있습니다. –

+0

+1 .... 나는 너와 동의 할 것이다 .... – Sandy

관련 문제