我有一个Dictionary<int, List<MyType>>
类型的变量,其中MyType是一个具有多个属性和方法的类。我只显示两个属性而没有方法,因为它们与问题无关。
class MyType
{
private string property1;
private double property2;
public string Property1
{
get { return property1; }
set { property1 = value; }
}
public double Property2
{
get { return property2; }
set { property2 = value; }
}
我想迭代字典并找到类实例的属性(例如Property2)具有特定值的所有类实例。
有了这个,我想修改属性的值并执行其他计算。
我一直在寻找如何做到这一点,但似乎找不到任何有用的东西。我查看了.ToLookup()
方法,但我不确定如何在此上下文中使用它。任何帮助将不胜感激。
答案 0 :(得分:3)
您可以使用两个foreach循环和LINQ .Where
扩展方法:
using System.Linq;
// ...
foreach (KeyValuePair<int, List<MyType>> kv in dict)
{
foreach (MyType t in kv.Value.Where(v => v.Property2 == 2.0))
{
// Use t for further calculations
}
}
如果你想要一个无LINQ的解决方案,你可以在内部循环中使用if语句:
foreach (KeyValuePair<int, List<MyType>> kv in dict)
{
foreach (MyType t in kv.Value)
{
if (t.Property2 != 2.0) continue;
// Use t for further calculations
}
}
答案 1 :(得分:2)
要迭代字典,请使用KeyValuePair<TKey,TValue>
类。由于您有一个列表作为您的值,您需要在字典的迭代中嵌套循环。这是一个假设myDictionary
为Dictionary<int, List<MyType>>
的示例:
foreach(var keypair in myDictionary)
{
foreach(MyClass m in keypair.Value.Where(v => v.Property1.Equals("something"))
{
//do whatever you want here with m being an object in the list of MyClass
}
}
LINQ Where
语句采用lambda,每当lambda返回true时,这些对象将成为列表迭代的一部分。
如果您只想从内部列表中选择IEnumerable<MyClass>
并且您不关心密钥,则可以执行以下操作:
var iterableMyClass = myDictionary.SelectMany(kv => kv.Value)
.Where(v => v.Property2.Equals("something"));
现在iterableMyClass
是一个IEnumerable<MyClass>
对象,它组合了字典中的所有列表。这是因为SelectMany
用于“扁平化”&#39;多个集合。 Where操作还以与第一个示例中IEnumerable
循环中相同的方式过滤返回的foreach
。
使用这个单个IEnumerable,您可以使用简单的foreach(MyClass m in iterableMyClass)
迭代匹配的所有对象。
修改强>
根据我们下面的讨论,如果您需要计算或告知IEnumerable是否包含至少一个项目,您可以执行以下任一操作。
要获得匹配计数,您只需在IEnumerable对象上调用.Count()
,但如果您根本不需要这些对象,则可以执行以下操作:
var count = myDictionary.SelectMany(kv => kv.Value).Count(v => v.Property2.Equals("something");
要获得布尔值,确定是否至少有一个匹配项,但不需要匹配的对象:
bool atLeastOne = myDictionary.SelectMany(kv => kv.Value).Any(v => v.Property2.Equals("something");