1

以下のネストされたループごとにLinqに変換しようとしています。しかし、私はまだそれをうまく行うことができません。

var objAct = new List<InformaticsBenchmarkSummary>();
foreach (var item in op)
{
    foreach (var lstTp5 in lstTopFive)
    {
        if (item.UnitOfOperations.ContainsKey(lstTp5.SystemID))
        {
            var objIbm = new InformaticsBenchmarkSummary();
            objIbm.CompanyId = item.CompanyId;
            objIbm.CompanyName = item.CompanyName;
            objIbm.LocationId = item.LocationId;
            objIbm.LocationName = item.LocationName;
            objIbm.UnitOfOperations.Add(lstTp5.SystemID, 
                                        item.UnitOfOperations[lstTp5.SystemID]);
            objAct.Add(objIbm);
        }
    }
}

UnitOfOperationsタイプはどこですかDictionary<int,string>();
op再びList<InformaticsBenchmarkSummary>()
lstTopFiveですList<int>()

私はこのようなことを試みましたが、構文的に失敗しました

var output = from item in op
from lstTp5 in lstTopFive
where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
let v = new InformaticsBenchmarkSummary()
{
     CompanyId = item.CompanyId,
     CompanyName = item.CompanyName,
     LocationId = item.LocationId,
     LocationName = item.LocationName
}
.UnitOfOperations.Add(lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID])
select v;

ネストされたループは完全に機能しますが、これをlinqするとパフォーマンスが向上すると思います。助けに感謝します。

4

4 に答える 4

2

Linq クエリ構文UnitOfOperations.Addでは、select で を使用することはできません。しかし、メソッドチェーンとメソッドを使用してそれを行うことができますSelectMany:

var objAcu = (op.SelectMany(item => lstTopFive, (item, lstTp5) => new { item, lstTp5 })  // <- Bad readability
                .Where(t => t.item.UnitOfOperations.ContainsKey(t.lstTp5.SystemID))
                .Select(t =>
                        {
                            var objIbm = new InformaticsBenchmarkSummary
                            {
                                CompanyId = t.item.CompanyId,
                                CompanyName = t.item.CompanyName,
                                LocationId = t.item.LocationId,
                                LocationName = t.item.LocationName
                            };
                            objIbm.UnitOfOperations.Add(t.lstTp5.SystemID, t.item.UnitOfOperations[t.lstTp5.SystemID]);
                            return objIbm;
                        })).ToList();

プロパティUnitOfOperationsに public があるset場合、この場合、クエリ構文を使用できます。

1 をどのように置き換えforeachますか? によってfrom ... in ...

次に、 2 を置き換えるには、 2foreachを使用しますfrom ... in ...

var objAct = (from item in op  // First foreach loop
              from lstTp5 in lstTopFive  // Second foreach loop
              where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
              select new InformaticsBenchmarkSummary
              {
                  CompanyId = item.CompanyId,
                  CompanyName = item.CompanyName,
                  LocationId = item.LocationId,
                  LocationName = item.LocationName,
                  UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }
              }).ToList();

しかし、そのような操作でパフォーマンスが向上するとは思えません。

とにかく、あなたが何を達成しようとしているのか理解できません。出力のすべての項目で、ディクショナリに要素が 1 つだけあるためUnitOfOperationsです。本当にやりたいことですか?

アップデート

List<int> systemIdTop5 = lstTopFive.Select(tp5 => tp5.SystemID).ToList();
var objAct = (from item in op
              select new InformaticsBenchmarkSummary
              {
                  CompanyId = item.CompanyId,
                  CompanyName = item.CompanyName,
                  LocationId = item.LocationId,
                  LocationName = item.LocationName,
                  UnitOfOperations = systemIdTop5.Intersect(item.UnitOfOperations.Keys)
                                                 .ToDictionary(systemId => systemId, systemId => item.UnitOfOperations[systemId])
              }).ToList();
于 2013-02-05T11:38:09.107 に答える
1

あなたは近くにいますが、voidそのようなLINQクエリでreturningメソッドを使用することはできません。(そして、それがvoid戻ってこなかった場合、それvはの結果でありAdd()、それはおそらく間違っているでしょう。)

の新しいを作成する場合はDictionaryUnitOfOperations他のプロパティと同じ方法で設定できます。しかし、それができない場合(おそらくUnitOfOperationsプライベートセッターがあるため)、またはしたくない場合(UnitOfOperations保持したい値に初期化されているため)、C#のあまり知られていない機能を使用できます:内部のコレクション初期化子オブジェクト初期化子:

UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }

このコードの効果は、次のように記述した場合と同じです。

createdObject.UnitOfOperations.Add(lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID]);

唯一の違いは、ステートメントではなく、式の一部であるということです。つまり、LINQクエリで使用できます。

その場合、クエリ全体は次のようになります。

var output = from item in op
             from lstTp5 in lstTopFive
             where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
             select new InformaticsBenchmarkSummary()
             {
                 CompanyId = item.CompanyId,
                 CompanyName = item.CompanyName,
                 LocationId = item.LocationId,
                 LocationName = item.LocationName,
                 UnitOfOperations =
                 {
                     { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] }
                 }
             };
于 2013-02-05T11:57:12.357 に答える
1

私が知る限り、あなたが問題を抱えているのはあなたの UnitOfOperations です。コンストラクターで初期化されている場合は、これを使用できます。

            var output = from item in op
                     from lstTp5 in lstTopFive
                     where item.UnitOfOperations.ContainsKey(lstTp5.SystemID)
                     select
                         new InformaticsBenchmarkSummary()
                             {
                                 CompanyId = item.CompanyId,
                                 CompanyName = item.CompanyName,
                                 LocationId = item.LocationId,
                                 LocationName = item.LocationName,
                                 UnitOfOperations = { { lstTp5.SystemID, item.UnitOfOperations[lstTp5.SystemID] } }
                             };

結果はです。IEnumerableリストにしたい場合は、 を呼び出しますoutput.ToList()

2 つの補足事項:

  1. これ以上速くなるとは思えません。それはまだ内側のループです。
  2. これにより、結果にほとんど重複した項目が生成される可能性があります (異なるUnitOfOperations) が、それが望ましいと思います。最悪のシナリオでは、 のすべてのアイテムにopUnitOfOperationsすべての が含まれ、のアイテムSystemIDlstTopFive合計が得られます。op.Count()*lstTopFive.Count()output
于 2013-02-05T12:19:18.370 に答える
0

これがUを助けますように:

var output = from item in op
                 join lstTp5 in lstTopFive on item.UnitOfOperations.Key equals lstTp5.SystemID
                 select new InformaticsBenchmarkSummary
                 {
                     CompanyId = item.CompanyId,
                     CompanyName = item.CompanyName,
                     LocationId = item.LocationId,
                     LocationName = item.LocationName,
                     UnitOfOperations = item.UnitOfOperations 
                 };
于 2013-02-12T04:41:03.390 に答える