LINQ を使用してこれを実行する方法をいくつか示します。また、提示した順序とは異なる順序で値が発生した場合に、値を正しく並べ替えます。たとえば、"(avg) Zeta" が "Zeta" の前にある場合、ソート後は後者が最初に来るはずです。
上記の内容に合わせて並べ替えたサンプル リストを次に示します。
var myUnsortedList = new List<string>
{
"Alpha",
"(avg) Alpha",
"(avg) Zeta",
"Zeta",
"Beta",
"(avg) Beta"
};
ラムダ構文
string prefix = "(avg)";
var result = myUnsortedList.Select(s => new
{
Value = s,
Modified = s.Replace(prefix, "").TrimStart(),
HasPrefix = s.StartsWith(prefix)
})
.OrderByDescending(o => o.Modified)
.ThenBy(o => o.HasPrefix)
.Select(o => o.Value);
ジップ・アグリゲート
string prefix = "(avg)";
var avg = myUnsortedList.Where(o => o.StartsWith(prefix))
.OrderByDescending(o => o);
var regular = myUnsortedList.Where(o => !o.StartsWith(prefix))
.OrderByDescending(o => o);
var result = regular.Zip(avg, (f, s) => new { First = f, Second = s })
.Aggregate(new List<string>(), (list, o) =>
new List<string>(list) { o.First, o.Second });
クエリ構文と文字列分割
これはラムダ構文に似てprefix
いますが、接頭辞を持つ文字列を判別するために を使用していない点が異なります。代わりに、スペースで分割しています。分割結果に複数の項目がある場合は、プレフィックスがあると想定しています。次に、値とプレフィックスの可用性に基づいて注文します。
var result = from s in myUnsortedList
let split = s.Split(' ')
let hasPrefix = split.Length > 1
let value = hasPrefix ? split[1] : s
orderby value descending, hasPrefix
select s;