4

ネストされた「for」ループを使用して現在実行しているC#の2つのコレクションを比較したいと思います。Linqに同じことを行う方法はありますか?それはより速くより効率的になりますか?これが私の現在のコードで、効率的な方法を探しているだけで完璧に機能します。

OrgCollection myYears = Org.RetrieveDistinctYear();
if (myYears.Count > 0)
{
AcademicYearCollection allYears = AcademicYear.RetrieveAll();
for (int i = 0; i < myYears.Count; i++)
{
    for (int j = 0; j < allYears.Count; j++)
    {
        if (myYears[i].AcademicYearCode == allYears[j].Code)
        {
        ddlYear.Items.Insert(0, new ListItem(allYears[j].Name,allYears[j].Code));
        break;
        }
    }
}
}

AcademicYearCollectionの「Code」をOrgCollectionの「AcademicYearCode」プロパティと比較したいのですが、同じ場合はドロップダウンリスト「ddlYear」に追加します。

前もって感謝します。

4

4 に答える 4

14

LINQで実行できます。これにより、コードが短くなります。それがより効率的であるかどうかを知るために、あなたはそれをプロファイリングする必要があるでしょう。linqの結合演算子は、特にコレクションが大きい場合に、パフォーマンスを向上させるために、ある種のハッシュバケットを内部的に使用していると思います。現在のソリューションはO(N ^ 2)であり、オプションの数が増えるとすぐに低下します。

OrgCollection myYears = Org.RetrieveDistinctYear();
AcademicYearCollection allYears = AcademicYear.RetrieveAll();

var items = from y in myYears
            join ay in allYears
            on y.Code equals ay.AcademicYearCode
            select new { ay.Name, ay.Code }
于 2012-07-05T12:46:34.230 に答える
0
OrgCollection myYears = Org.RetrieveDistinctYear();
if (myYears.Count > 0)
{
    AcademicYearCollection allYears = AcademicYear.RetrieveAll();
    for (int i = 0; i < myYears.Count; i++)
    {
         if (allYears[j].Any(allY => allY ==  myYears[i].AcademicYearCode ))
            {
                ddlYear.Items.Insert(0, new ListItem(allYears[j].Name, allYears[j].Code));
                break;
            }

    }
}

これはオプションかもしれませんが、拡張メソッド'any'は反復を行うことで同じように機能すると思います。

于 2012-07-05T12:49:47.273 に答える
0

これはどう

var allYears = AcademicYear.RetrieveAll().ToDictionary(y => y.Code, y.Name);

ListItem match = null;
foreach(var year in Org.RetrieveDistinctYear())
{
    if (allYears.HasKey(year.AcademicYearCode)
    {
        match = new ListItem(
                       allYears[year.AcademicYearCode], 
                       year.AcademicYearCode);
        break;
    }
}

if (match != null)
{
    ddlYear.Items.Insert(0, match); 
}

ここを使用するDictionaryと、優れたパフォーマンスが提供され、Org.RetrieveDistinctYearの結果が一致するほど、より多くのメリットが得られます。の結果RetrieveDistinctYearが短いことが多い場合、または一致が最上位にある場合、辞書作成のオーバーヘッドにより、コードが不必要に遅くなります。


編集

またはこのアプローチ

var allYears = AcademicYear.RetrieveAll().ToDictionary(y => y.Code, y.Name);

var matchingCode = Org.RetrieveDistinctYear()
    .Select(y = y.AcademicYearCode)
    .FirstOrDefault(code => allYears.HasKey(code));

if (!string.IsEmptyOrWhitespace(matchingCode))
{
    ddlYear.Items.Insert(0, new ListItem(
                                 allYears[matchingCode], 
                                 matchingCode)); 
}
于 2012-07-05T13:03:46.773 に答える
0

このソリューションは、元のソリューションと同様の速度と効率を備えていますが、に変更from y in myYearsfrom y in myYears.AsParallel()て並列化することで、場合によっては速度を上げることができます。

OrgCollection myYears = Org.RetrieveDistinctYear();
AcademicYearCollection allYears = AcademicYear.RetrieveAll();

var items = from y in myYears
            let match = allYears.FirstOrDefault( ay => y.AcademicYearCode == ay.Code)
            where match != null
            select new ListItem(match.Name, match.Code);
于 2012-07-05T23:16:53.883 に答える