「Issue」オブジェクトのリストがあり、「Priority」フィールドで並べ替えたいと思います。
問題は、「Priority」が「HIGH」、「MEDIUM」などの文字列名であるため、並べ替えることができるIDがないことです。「HIGH」が「MEDIUM」よりも高く、「LOW」よりも高いことをソーターに分類して伝えるにはどうすればよいですか?
「Issue」オブジェクトのリストがあり、「Priority」フィールドで並べ替えたいと思います。
問題は、「Priority」が「HIGH」、「MEDIUM」などの文字列名であるため、並べ替えることができるIDがないことです。「HIGH」が「MEDIUM」よりも高く、「LOW」よりも高いことをソーターに分類して伝えるにはどうすればよいですか?
明らかな方法は次のとおりです。
string[] priorities = { "LOW", "MEDIUM", "HIGH" };
var orderedIssues = issues.OrderByDescending
(issue => Array.IndexOf(priorities, issue.Priority));
ただし、列挙型の使用を検討してください。
public enum Priority
{
Low,
Medium,
High
}
var orderedIssues = issues.OrderByDescending
(issue => (Priority)Enum.Parse(typeof(Priority), issue.Priority, true));
さらに良いのは、列挙型をプロパティ/フィールド自体の型として使用することです。この場合、列挙型は次のように単純です(エラーが発生しにくくなります)。
var orderedIssues = issues.OrderByDescending(issue => issue.Priority);
最も簡単な方法はおそらく次のようになります。
private static int MapPriority(string priority)
{
switch(priority.ToUpperInvariant())//skip the case bit if safe
{
case "HIGH":
return 1;
case "MEDIUM":
return 2;
case "LOW":
return 3;
default:
return 4;
}
}
var sorted = someCollection.OrderBy(i => MapPriority(i.PriorityProperty));
db-backedフォームでは、呼び出すことができるDB内の関数が必要になります。これはメモリ内のみです。
可能な値がたくさんあるので、私はそれを手作業ではなく辞書に基づいています。ただし、この場合のように3つを手動でコーディングします(使用される値が変更されない限り、辞書ベースのアプローチを作成するさらに複雑な方法が唯一の方法です)。
かなりの数のそのようなアイテムをソートする場合、またはこれを頻繁に呼び出す場合は、IComparer<T>
実装を使用するか、アイテム自体に実装を依頼しますIComparable<T>
。
この特定のケースでは、LinqのOrderBy
方法を使用することもできます。
var sortedList = issueList.OrderBy(i=>
i.Priority == "HIGH"
? 1
: i.Priority == "MEDIUM"
? 2
: 3).ToList();
ワンライナーとして、これはそれほど悪くはないでしょう。文字列を配列、リスト、または辞書に並べ替えたい順序で配置することもできます(または、辞書の場合は値として並べ替え順序を含めることができます)。
OrderByを使用することの1つの欠点は、リストを結果に再割り当てすることによって指示しない限り、ソースリストに影響を与えないことです。いずれの場合も、2つの追加コレクションが作成されます。OrderBy内で内部的に使用される配列またはリスト(並べ替えには、並べ替えるコレクション全体の知識が必要です)およびToList()によって生成されるリスト。したがって、これにはO(2N)の追加メモリが必要ですが、List.Sort()はインプレースである可能性があります(実際にインプレースであるかどうかはわかりませんが、通常はインプレースであるQuickSortを使用します)。
public enum Priority
{
LOW = 1,
MEDIUM = 2,
HIGH = 3
}
issues.OrderByDescending(issue=>issue.Priority);
このようなもの:
List<Issue> issues = ...;
var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);