テーブルからいくつかの列値のリストがあるとしましょう。空の文字列と重複値を削除するにはどうすればよいですか。次のコードをご覧ください。
List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
これは私が今コーディングしたものですが、Amiramのコードははるかにエレガントなので、ここで答えを選択します:
DataTable dtReportsList = someclass.GetReportsList();
if (dtReportsList.Rows.Count > 0)
{
List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
dtList.RemoveAll(x=>x == "");
dtList = dtList.Distinct().ToList();
rcboModule.DataSource = dtList;
rcboModule.DataBind();
rcboModule.Items.Insert(0, new RadComboBoxItem("All", "All"));
}
dtList = dtList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList()
空の文字列と空白はnullのようなものだと仮定しました。そうでない場合は、IsNullOrEmpty
(空白を許可)、またはs != null
を使用できます
Amiramの答えは正しいが、実装されているDistinct()はN2 操作;リスト内の各アイテムについて、アルゴリズムはそれをすでに処理されているすべての要素と比較し、一意の場合はそれを返し、そうでない場合は無視します。もっとうまくやれる.
ソート済みリストは線形時間で重複排除できます。現在の要素が前の要素と等しい場合は無視し、そうでない場合は返します。並べ替えはNlogNなので、コレクションを並べ替える必要がある場合でも、いくつかの利点があります。
public static IEnumerable<T> SortAndDedupe<T>(this IEnumerable<T> input)
{
var toDedupe = input.OrderBy(x=>x);
T prev;
foreach(var element in toDedupe)
{
if(element == prev) continue;
yield return element;
prev = element;
}
}
//Usage
dtList = dtList.Where(s => !string.IsNullOrWhitespace(s)).SortAndDedupe().ToList();
これは同じ要素を返します。並べ替えられただけです。
Amiram Korachのソリューションは確かに整然としています。汎用性のための代替手段を次に示します。
var count = dtList.Count;
// Perform a reverse tracking.
for (var i = count - 1; i > -1; i--)
{
if (dtList[i]==string.Empty) dtList.RemoveAt(i);
}
// Keep only the unique list items.
dtList = dtList.Distinct().ToList();