[英]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>()
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就可以提高性能。 感謝任何幫助。
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
只有一個且只有一個元素。 這真的是你想要做的嗎?
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()
。
兩個旁注:
UnitOfOperations
),但我想這是期望的。 在最壞的情況下在所有項目op
有UnitOfOperations
包含所有SystemID
在lstTopFive
給我們一個總的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.