在 C# 中查找 List of List 中的元素

7
我有一个嵌套列表如下:
List> userList
类T { string uniqueidentifier, string param2, int param2}
我有一个uniqueidentifier,需要在列表中找到具有相同“uniqueidentifier”值的元素T。
我可以使用两个foreach循环来完成。但这似乎不是一个好的方式。我猜应该有一些内置方法像“Find”,做同样的事情并高度优化。
5个回答

18

Find没有被优化,因为它执行线性搜索,这是在未排序列表上唯一有意义的操作。如果想要更好的代码书写方式,可以使用LINQ:

var element = (from sublist in userList
               from item in sublist
               where item.uniqueidentifier == someid
               select item).FirstOrDefault();

超酷。太棒了。我真的很惊讶 Linq 的强大。你能给我指一些好的 LINQ 资源吗? - Sandy

2
我建议你将外部列表更改为字典,这样你就可以使用其唯一标识符查找内部列表。
     Dictionary<string, List<T>> myDictionary = new Dictionary<string,List<T>>();
     myDictionary["1"] = innerList;
     List<T> list = myDictionary["1"]; //find list with unique id "1"

唯一标识符是该项的标识符,而不是内部列表的标识符。这意味着一个内部列表具有多个唯一标识符,就像它包含的项一样。 - Yann
简洁明了的想法 ;) - Sharif Yazdian

2

如果不进行索引/哈希,即使使用“高度优化”的查找算法也无济于事。最好的方法是改变数据的存储方式,例如使用树结构。

如果不改变存储机制,在多核系统上并行搜索是最好的选择。


是的,我需要尝试不同的存储方法。但我发现cdhowie提供的使用LINQ的答案非常有用。它似乎相当快,但我还没有在大型列表上进行过真正的尝试。更改数据存储为树是否比LINQ更快? - Sandy
在LINQ的背后,它并不会像魔法一样做任何不同的事情。它唯一能做的就是延迟使用结果,换句话说,直到你使用它时才进行惰性加载。cdhowie非常小心地说“更好的编写方式”,而不是“执行更快的搜索”。 - Andrew T Finnell

1

试试这个:

var query =
    from ts in userList
    from t in ts
    where t.uniqueidentifier == uniqueidentifier
    select t;

var user = query.FirstOrDefault();

0

不确定这是否有效..

var match = userList.Where(x=> x.Any(y=>y.uniqueidentifier = "blah"));

这将找到包含具有该标识符的项的内部列表;它不会找到该项本身。 - cdhowie
@cdhowie,是的,你说得对,可以轻松地获得它,但这将需要再次搜索列表,这将是低效的,绝不是一个好的解决方案! - Paul Creasey
1
这就是为什么你想要使用SelectMany。请看我的答案——编译后的代码将使用SelectMany将嵌套的列表结构展平成一个长序列的元素。 - cdhowie
@cdhowie:啊,谢谢。虽然我写过很多像你回答中的查询,但我不知道它的lambda形式。 - Paul Creasey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接