将foreach循环转到Linq
本文关键字:Linq 循环 foreach | 更新日期: 2023-09-27 18:26:27
是否有要写的东西?将每个循环的这个变成Linq表达式:
private List<string> datasetItemset;
Dictionary<string, int> itemsetScanning = new Dictionary<string, int>();
List<string> itemList = new List<string>();
foreach (string transaction in this.datasetItemset)
{
string[] items = transaction.Split(new char[] { ' ' });
foreach (string item in items)
if (!itemList.Contains(item))
{
itemList.Add(item);
itemsetScanning.Add(item, 0);
}
}
我的下一个问题是,使用linq表达式而不是foreach循环是否会加快程序的性能,我对这个linq有点陌生。
更新:使用过多的foreach循环会减慢我的程序速度。
使用linq表达式而不是foreach循环确实提高了程序的性能,我对这个linq有点陌生。
没有。在内部,LINQ通常仍然会执行相同数量的迭代,所以一般来说,它不会加快速度。如果编写得当,LINQ将执行与循环非常相似的操作。
使意图更加清晰是非常有用的,这反过来有时可以使优化变得更简单,缩短流程。也就是说,同样的优化也可以很容易地在循环上完成。
有没有什么可以写的?把每个循环的这个变成Linq表达式:
是的。这可以通过以下方式完成:
foreach(var item in this.datasetItemset
.SelectMany(transaction => transaction.Split(' '))
.Distinct())
{
itemList.Add(item);
itemsetScanning.Add(item, 0);
}
请注意,内部主体/循环被保留为foreach
循环,在这种情况下,这是故意的,因为它正在执行副作用。
假设你正在构建列表和集合,你可以使用:
var itemList = this.datasetItemset.SelectMany(transaction => transaction.Split(' ')).ToList();
var uniqueSet = new HashSet<string>(itemList); // Build the set from the list
这将为您提供一组唯一的值(作为HashSet<string>
)以及值列表。如果你只需要一个唯一的值列表,你可以使用Distinct
直接构建它:
var uniqueItemList = this.datasetItemset
.SelectMany(transaction => transaction.Split(' '))
.Distinct()
.ToList();
如果你需要字典,那么它只需要以下结果:
var itemsetScanning = uniqueItemList.ToDictionary(i => i, i => 0);
这里是丑陋的linq
foreach (var item in this.datasetItemset
.Select(transaction => transaction.Split(new char[] { ' ' }))
.SelectMany(items => items
.Where(item => !itemList.Contains(item))))
{
itemList.Add(item);
itemsetScanning.Add(item, 0);
}
List<string> itemList = this.datasetItemset
.SelectMany(item => item.Split(' '))
.Distinct()
.ToList();
var itemsetScanning = itemList.ToDictionary(e => e, _ => 0);
关于性能,Linq将比精心设计的特定解决方案慢,但它通常足够快。如果性能对您来说是一个问题,您可能应该避免它(在分析之后)。
以下是我如何编写代码:
var itemList = datasetItemset.SelectMany(transaction => transaction.Split(' '))
.Distinct()
.ToList();
var itemsetScanning = itemList.ToDictionary(transaction => transaction,
transaction => 0);
这是解决问题的更惯用的LINQ方法。
嵌套的foreach通常映射到SelectMany
调用,您可以使用Distinct
,而不是检查该项是否已经存在,它不仅在语义上表示您要做的事情,而且会明显更高效(因为您避免了在列表中重复线性搜索;如果您愿意,您可以在非LINQ解决方案中使用HashSet
来更高效地搜索)。您可以使用ToList
和ToDictionary
将每个序列直接转换为集合,而不是将项添加到集合中,以避免显式使用foreach
。
您可以使用LINQ:轻松完成同样的操作
var itemList = this.datasetItems
.SelectMany(x => x.split(' '))
.Distinct()
.ToList();
var itemssetScanning = itemList.ToDictionary(x => x, x => 0);
然而,在SelectMany
、Distinct
、ToList
和ToDictionary
方法中仍然隐藏着foreach
循环这里没有魔法额外的委托调用会使其速度慢于自定义循环。