嵌套的 ForEach 循环到 Linq
本文关键字:Linq 循环 ForEach 嵌套 | 更新日期: 2023-09-27 17:57:58
我正在尝试将每个循环的嵌套下面转换为 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
。但是您可以使用方法链和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
,在这种情况下,您可以使用查询语法。
你如何更换 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();
据我所知,您遇到的是您的操作单元。如果在构造函数中初始化,则可以使用以下命令:
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
中的所有项目都有一个包含lstTopFive
中所有SystemID
的UnitOfOperations
,从而使我们output
中总共有op.Count()*lstTopFive.Count()
个项目。
您已经很接近了,但您不能像这样在 LINQ 查询中只使用 void
返回方法。(如果不是void
返回,那么v
将是Add()
的结果,这很可能是错误的。
如果要为 UnitOfOperations
创建新Dictionary
,可以采用与其他属性相同的方式进行设置。但是,如果您不能这样做(可能是因为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] }
}
};
愿这对你有帮助:
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
};