在不使用循环的情况下在ObservableCollection中查找项

时间:2012-05-08 12:10:45

标签: c# wpf collections

目前我有以下语法(list是包含具有许多不同属性的对象的列表(其中Title是其中之一):

for (int i=0; i < list.Count; i++)
{
   if(title == list[i].Title)
   {
    //do something
   }
}

如何在不必遍历整个集合的情况下访问list[i].Title?由于我的列表越来越大,这可能会影响我的程序的性能。

我的程序中有很多类似的语法(通过for循环和索引访问公共属性)。但是我确定必须有一种更好,更优雅的方式吗?

由于我的列表包含对象,因此find方法似乎是一个选项。

10 个答案:

答案 0 :(得分:43)

我不知道完全是什么意思,但从技术上讲,这是不可能的没有循环。

可能是指使用LINQ,例如:

list.Where(x=>x.Title == title)

值得一提的是,迭代结束不会被跳过,而是简单地包含在LINQ查询中。

希望这有帮助。

编辑

换句话说,如果您真的关注性能,请按照您已经做的方式进行编码。否则,请选择LINQ以获得更简洁明了的语法。

答案 1 :(得分:31)

Linq来了:

var listItem = list.Single(i => i.Title == title);

如果没有与谓词匹配的项,则抛出异常。或者,有SingleOrDefault

如果你想要一个与标题匹配的项目集合,那就是:

var listItems = list.Where(i => i.Title ==  title);

答案 2 :(得分:5)

如果你不需要索引

,我必须将它用于条件添加
using System.Linq;

使用

if(list.Any(x => x.Title == title){
// do something here
}

这将告诉您任何变量是否满足您的给定条件。

答案 3 :(得分:3)

考虑创建索引。字典可以做到这一点。如果你需要列表语义,子类并将索引保​​持为私有成员......

答案 4 :(得分:3)

我建议将它们存储在Hashtable中。然后,您可以使用密钥访问集合中的项目,这是一种更有效的查找。

var myObjects = new Hashtable();
myObjects.Add(yourObject.Title, yourObject);
...
var myRetrievedObject = myObjects["TargetTitle"];

答案 5 :(得分:1)

您正在寻找一个基于散列的集合(如Dictionary或Hashset),ObservableCollection不是。最好的解决方案可能是从基于哈希的集合派生并实现INotifyCollectionChanged,它将提供与ObservableCollection相同的行为。

答案 6 :(得分:1)

ObservableCollection是一个列表,所以如果您不知道元素位置,则必须先查看每个元素,直到找到预期的元素。

可能的优化 如果您的元素已排序,请使用二进制搜索来提高性能,否则请使用Dictionary作为索引。

答案 7 :(得分:0)

如果您有N个对象,并且需要获取所有这些对象的标题,则必须使用循环。如果你只需要标题并且你真的想要改进它,也许你可以制作一个只包含标题的分离数组,这样可以提高性能。 您需要在说这可能会损害性能之前定义可用内存量和可以处理的对象数量,并且在任何情况下解决方案都将改变程序的设计而不是算法。

答案 8 :(得分:0)

也许这种方法可以解决问题:

int result = obsCollection.IndexOf(title);

IndexOf(T)
搜索指定的对象,并返回整个Collection中第一次出现的从零开始的索引。

(继承自Collection)

https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netframework-4.7.2#methods

答案 9 :(得分:-1)

一个可观察的集合可以是一个列表

{
    BuchungsSatz item = BuchungsListe.ToList.Find(x => x.BuchungsAuftragId == DGBuchungenAuftrag.CurrentItem.Id);
}