簡體   English   中英

嵌套的ForEach循環到Linq

[英]Nested ForEach loop to Linq

我試圖將下面的每個循環嵌套轉換為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>()
lstTopFiveList<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就可以提高性能。 感謝任何幫助。

Linq查詢語法中不可能在UnitOfOperations.Add中使用UnitOfOperations.Add 但是你可以使用Method Chain和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具有公共set ,則在這種情況下,您可以使用query-syntax。

你如何取代1 foreach from ... in ...

然后,要替換2個foreach ,請使用2 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();

但我懷疑它會提高這種操作的性能。

無論如何,我不明白你想要達到的目標。 因為在輸出的所有項目中將在字典UnitOfOperations只有一個且只有一個元素。 這真的是你想要做的嗎?

UPDATE

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();

你很接近,但你不能在LINQ查詢中使用void返回方法。 (如果它不是void返回,則v將是Add()的結果,這很可能是錯誤的。)

如果要為UnitOfOperations創建新的Dictionary ,可以將其設置為與其他屬性相同的方式。 但是如果你不能這樣做(可能是因為UnitOfOperations有一個私有的setter)或你不想(因為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] }
                 }
             };

據我所知,你的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()

兩個旁注:

  1. 我不相信這會更快。 它仍然是一個內循環。
  2. 這可能會在結果中產生幾乎重復的項目(不同的UnitOfOperations ),但我想這是期望的。 在最壞的情況下在所有項目opUnitOfOperations包含所有SystemIDlstTopFive給我們一個總的op.Count()*lstTopFive.Count()中的項目output

願這有助於你:

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 
                 };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM