在字典中搜索值的最佳方法是什么。 例如,我想搜索修改过的对象,是否会通过整个集合来实现这一目的?
c#,。net 2.0
class RecA
{
public bool modified {get;set:}
public string txt {get;set;}
}
class RecA_Dic : Dictionary<int,Rec_A>
{
public bool GetItemByKey(int key,out obj)
{
return this.TryGetValue(key, out obj);
}
public List<Rec_A> getModifiedItems()
{
List<Rec_A> li = new List<Rec_A>();
for(int i=0;i<this.count;i++)
if (((Rec_A)this[i]).modified == true)
li.Add((Rec_A)this[i]);
return li;
}
}
答案 0 :(得分:7)
鉴于约束(.NET 2.0),您几乎达到目标。 IEnumerable<Rec_A>
加yield return
是一个更好的选择,IMO:
public IEnumerable<Rec_A> getModifiedItems()
{
foreach (Rec_A rec in this.Values)
{
if (rec.modified)
yield return rec;
}
}
答案 1 :(得分:2)
是的,字典只能快速查找密钥。如果你想在值中寻找任何东西,你必须遍历整个集合。
如果您经常这样做,您可以在您的收藏中放置一个列表,该列表仅跟踪修改的项目。修改集合时会有更多的开销,因为列表也必须更新,但只获得修改后的项目将非常快。
答案 2 :(得分:1)
搜索整个字典当然是最简单的方法,尽管foreach
循环会更清晰:
foreach (KeyValuePair<int, Rec_A> kvp in d)
{
// Check kvp.Value
}
如果希望查找更快,可以在修改它们时将修改后的对象添加到单独的列表中。这会减慢修改速度,所以这里需要进行权衡。
答案 3 :(得分:1)
您的问题的基本答案是肯定的,您必须遍历这些值才能找到修改过的值。
现在,这个答案的其余部分将像代码审查一样阅读。当我读到你觉得不得不这么做的代码时,脑子里响起了很多警告。
1)首先关闭你的代码甚至工作。那是因为您将Dictionary
类索引中的密钥视为List
或Array
。您的for
循环在{0}处开始i
并将其递增到Count
(顺便说一下,这是KeyValuePair
的数量)。但是,如果Dictionary
中的值没有等于0的值,该怎么办?基本上你会得到这样的例外:
RecA_Dic myD = new RecA_Dic();
myD.Add(10,new Rec_A());
myD.getModifiedItems(); //throws KeyNotFoundException
现在,如果您要使用基于零的索引向Dictionary
添加值,那么这就引出了为什么在Dictionary
会使用List
时会出现问题的问题?
2)你不需要在this[i]
上进行演员表。由于您告诉Dictionary
它将包含Rec_A
个值,因此会将值返回为Rec_A
。这就是仿制药之美。
3)您无需在modified
语句中将true
与if
进行比较。使用bool
变量时,通常认为这是一种很好的礼节,不能将它们与true
或false
进行比较。另外,您可能需要考虑将modified
重命名为IsModified
。这更好地遵循许多标准命名约定并使代码更具可读性。
4)尽可能尝试使用foreach
代替for
。在这种情况下,foreach
实际上会解决我在1中提到的问题。
5)正如Humberto所提到的,你可能想要考虑返回IEnumerable
并使用yield return
。这为您提供了延迟执行的好处。
6)最后你为什么要继承Dictionary
?根据您的代码,我猜您可以创建一个Dictionary
并制作getModified
方法static
并使其成为Dictionary
(或List
,如果是所有你真正需要的)作为参数。
我希望我的一些建议可以帮助你。
答案 4 :(得分:0)
是。要么必须检查每个值,要么必须跟踪另一个数据结构中的更改,例如已修改对象的列表。 (您可以在专门的字典实现中隐藏它。)
答案 5 :(得分:0)
详细阐述Mark Byers的回应: 例如 假设我们有一个名为Family的类,它包含一些值(无论多少),我们构建了一个Dictionary来保存它的数据。 如果我们想搜索这个列表,我们写道:
foreach (KeyValuePair<string, Family> kvPair in familyListDictionary)
{
if (kvPair.Key == "4")
{
Console.WriteLine (kvPair);
}
}
如果我们搜索键&#34; 4&#34; ...(在我的情况下,TKey是一个字符串)。