「第3番」や「4位」など文字列中に数字が含まれる値のリストがある時、文字列中の数字を使って配列やリストを並べ替えたい時が稀にありますが、そのまま文字列でソートすると「文字コードの順」にソートされてしまいます。
そこで今回は、「文字列中の数字の順に配列やリストを並べ替える方法」を紹介します。
コード
- LINQを使って3段階で処理をしています。
- 最初のSelectメソッドで、listから得られた名称(Name)に加えて、名称中の数値部分(Index)という値の2つを保持した匿名クラスを作ります。
- 次にOrderByメソッドを使い、作成した匿名クラスの数値部分(Index)を使って昇順でソートします。
- 最後に再びSelectメソッドを使い、匿名クラスの名称(Name)部分だけを抽出して、名称(Name)部分からなるリスト(IEnumerable)を作ります。
- もっとスッキリした書き方が他にもあるかもしれません...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Samples
{
class OriginalSort
{
/// <summary>
/// ソートする配列。
/// </summary>
List<string> titles = new List<string> { "第17番", "第1番", "第2番", "第16番", "第5番" };
/// <summary>
/// 「第1番→第2番→第5番→第16番→第17番」というように、文字列中の数字の順に並べ替える。
/// </summary>
public void Sort()
{
// {Name,Index}という匿名クラスのリストを作り、Indexに従ってソートする。
var list = titles.Select(title => new { Name = title, Index = ToInt(title) })
.OrderBy(title => title.Index).Select(title => title.Name);
System.Console.WriteLine("[結果]" + string.Join("→", list));
}
/// <summary>
/// 引数の文字列から数値部分だけを抜き出して返す。
/// </summary>
/// <param name="txt">「第3番」や「4位」など、数値部分を含む文字列。</param>
/// <returns>抜き出された数値部分。</returns>
public int ToInt(string txt)
{
return int.Parse(Regex.Replace(txt, @"[^0-9]", ""));
}
}
}
実行結果
- OriginalSort#Sort()を実行すると、以下のように文字列中の数字の順に並べ替えた結果が得られます。
[結果]第1番→第2番→第5番→第16番→第17番