2017-12-21 8 views
1

によって:LINQ - 文字列のリスト - 唯一の手紙によるため、その後、例えば数字

この配列:

a 2 
a 10 
a 

ソートした後でなければなりません:

a 
a 2 
a 10 

私はこれを試してみてくださいしかし、それはうまくいかない:順序が間違っている。

... 
.OrderBy(s => s.name) 
.ThenBy(s => { 
    var stringNumber = Regex.Match(s.name, @"\d+").Value; 

    return string.IsNullOrEmpty(stringNumber) 
    ? 0 
    : int.Parse(stringNumber); 
}); 
+1

"うまくいかない"とはどういう意味ですか?そして、あなたの '名前'は常にこのように見えますか?単一の文字スペース番号? –

+0

あなたは何を出力しますか – Raizzen

+0

問題は、最初は**完全な文字列**で並べ替えるので、 'ThenBy'はもう効果がなく、' OrderBy'だけ文字だけ、 'ThenBy'は数字だけ必要です。 –

答えて

0

あなたは「手紙は」私はあなたにのみソート最初文字によって、それまでに数をしたいと仮定したので。

そうでないOrderBy全体文字列の操作を行いますが、文字だけで:

var result = list 
      .OrderBy(s => s.FirstOrDefault()) // only first character 
      .ThenBy(s => 
      { 
       var stringNumber = Regex.Match(s.name, @"\d+").Value; 
       return string.IsNullOrEmpty(stringNumber) ? 0 : int.Parse(stringNumber); 
      }) 

あなたのコードでは、最初に全体文字列でソートし、そのThenByはもう効果がなかったです。

0
var test = new[] {"a 2", "a 10", "a"}; 

var sorted = test.OrderBy(s => new string(s.Where(char.IsLetter).ToArray())).ThenBy(s => 
{ 
    var stringNumber = Regex.Match(s, @"\d+").Value; 
    return string.IsNullOrEmpty(stringNumber) ? 0 : int.Parse(stringNumber); 
}); 

これは、最初に文字で並べ替え、次に数字で並べ替える必要があります。

3

私は明示的に判断基準を抽出することをお勧め:正規表現でnamenumberグループ:

var list = new List<string>() { 
    "a", 
    "a 4", 
    "b 1", 
    "a 2", 
    "a 11" 
    }; 

    var result = list 
    .Select(item => new { 
     value = item, 
     match = Regex.Match(item, @"^(?<name>.*?)\s*(?<number>[0-9]*)$"), 
     }) 
    .OrderBy(item => item.match.Groups["name"].Value) 
    .ThenBy(item => item.match.Groups["number"].Value.Length) 
    .ThenBy(item => item.match.Groups["number"].Value) 
    .Select(item => item.value); 

テスト:

Console.WriteLine(string.Join(Environment.NewLine, result)); 

結果:

a 
a 2 
a 4 
a 11 
b 1 
+0

新しいタプルタイプがここで使用できることを述べる価値があります。 – Sweeper

1

は、あなたがそのような何かを試みることができます;

 var list = new List<string>() 
     { 
      "a ", 
      "a 4", 
      "b 1", 
      "a 2" 
     }; 

     int value = 0; 

     list = list 
      .Select(x => new { 
      WholeString = x, 
      StringPart = x.Split(' ')[0], 
      IntPart = int.TryParse(x.Split(' ')[1], out value) ? value : 0 
      }) 
      .OrderBy(x => x.StringPart) 
      .ThenBy(x => x.IntPart) 
      .Select(x => x.WholeString) 
      .ToList(); 
関連する問題