2016-06-27 3 views
2

実際には文字列のリストであり、数字と文字を含むシーン番号のリストをソートする必要があります。数字と文字を含む文字列を並べ替える

これは、私はそれだけで最初の番号を並べ替えているように見えます私に次のような結果

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

を与えてはComparer

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; 
    } 
} 
関連する問題