2016-06-27 2 views
2

실제로 문자열 목록에 숫자와 문자가 들어있는 장면 번호 목록을 정렬해야합니다. 숫자와 문자가 포함 된 문자열 정렬

나에게 그것은 단지 첫 번째 숫자를 정렬하는 것처럼 보이는

101-8 
101-8A 
101-9 
102-1 
103-4 
103-4B 
101-10 
101-11 
103-10 

다음과 같은 결과를 제공하는 비교 자

public class SceneComparer : IComparer 
{ 
    private readonly Regex sceneRegEx = new Regex(@"(\D*)(\w*)", RegexOptions.Compiled); 

    public int Compare(object x, object y) 
    { 
     Scene sceneX = x as Scene; 
     Scene sceneY = y as Scene; 

     var firstSceneMatch = this.sceneRegEx.Match(sceneX.SceneNumber); 

     var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value); 
     var firstSceneAlpha = firstSceneMatch.Groups[2].Value; 

     var secondSceneMatch = this.sceneRegEx.Match(sceneY.SceneNumber); 

     var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value); 
     var secondSceneAlpha = secondSceneMatch.Groups[2].Value; 

     if (firstSceneNumeric < secondSceneNumeric) 
     { 
      return -1; 
     } 

     if (firstSceneNumeric > secondSceneNumeric) 
     { 
      return 1; 
     } 

     return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);    
    } 
} 

다음

101-11 
102-1 
101-10 
101-8 
103-10 
101-8A 
101-9 
103-4 
103-4B 

내가 만들어 놓은 목록을하다 대시와 영숫자 앞에 있지만 대시 뒤의 번호는 정렬되지 않습니다. 원하는 결과를 얻습니다.

101-8 
101-8A 
101-9 
101-10 
101-11 
102-1  
103-4 
103-4B 
103-10 

원하는 결과를 얻는 방법에 대한 아이디어.

+1

"-"를 사용하여 문자열을 분할합니다. 단락 기호는 튜플 으로 분리 한 다음 LINQ를 사용하여 Item1, Item2 순으로 정렬합니다. – Yobik

답변

0

문자열에 Split 문자열을 입력하고 숫자를 추출해야 해당 필드에 대한 정렬을 요청할 수 있습니다.

// Assuming you have this... 
List<string> list = new List<string>() 
{ 
    "101-11", 
    "102-1", 
    "101-10", 
    "101-8", 
    "103-10", 
    "101-8A", 
    "101-9", 
    "103-4", 
    "103-4B" 
}; 


// You could do this. 
var result = list.Select(x=> 
    { 
     var splits = x.Split('-'); 
     return new 
     { 
      first = int.Parse(splits[0]), 
      second = int.Parse(Regex.Match(splits[1], @"\d+").Value), 
      item =x 

     }; 
    }) 
    .OrderBy(x=>x.first) 
    .ThenBy(x=>x.second) 
    .Select(x=>x.item) 
    .ToList(); 

확인이 Demo

0

당신은 매우 가깝습니다. Match 대신 Matches을 사용하십시오.

또한 정규식을 \D이 비영 문자를 캡처하므로 수정하십시오.

public class SceneComparer : IComparer 
{ 
    private readonly Regex sceneRegEx = new Regex(@"(\d+)(\w+)?", RegexOptions.Compiled); 

    public int Compare(object x, object y) 
    { 
     Scene sceneX = x as Scene; 
     Scene sceneY = y as Scene; 

     var firstSceneMatches = this.sceneRegEx.Matches(sceneX.SceneNumber); 
     var secondSceneMatches = this.sceneRegEx.Matches(sceneY.SceneNumber); 

     var matchesCount = Math.Min(firstSceneMatches.Count, secondSceneMatches.Count); 
     for (var i = 0; i < matchesCount; i++) 
     { 
      var firstSceneMatch = firstSceneMatches[i]; 
      var secondSceneMatch = secondSceneMatches[i]; 

      var firstSceneNumeric = Convert.ToInt32(firstSceneMatch.Groups[1].Value); 
      var secondSceneNumeric = Convert.ToInt32(secondSceneMatch.Groups[1].Value); 
      if (firstSceneNumeric != secondSceneNumeric) 
      { 
       return firstSceneNumeric - secondSceneNumeric; 
      } 

      var firstSceneAlpha = firstSceneMatch.Groups[2].Value; 
      var secondSceneAlpha = secondSceneMatch.Groups[2].Value; 
      if (firstSceneAlpha != secondSceneAlpha) 
      { 
       return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha); 
      } 
     } 

     return firstSceneMatches.Count - secondSceneMatches.Count; 
    } 
} 
관련 문제