英文:
Is "database indexing" possible on a C# List?
问题
Sure, here is the translated content:
我在C#中有一个IList<Node>
,而Node
是一个对象,具有Name
作为属性。
通常情况下,我需要在IList<Node>
中执行搜索,我是这样做的:
List_of_Nodes.Where(o => o.Name == "Something").FirstOrDefault();
我想知道是否有一种方法可以加速这个过程。
在数据库中,可以通过在要搜索的列上创建索引来更快地执行表内搜索。
在C#的IList
中是否也有这种可能呢?
(我一直在网站上寻找答案,但我总是得到像List_of_Nodes[index]
这样的结果。如果我能用List_of_Nodes[name]
替换搜索就太好了,但我该如何实现呢?)
英文:
I have a IList<Node>
in C#, and a Node
is an object, having Name
as a property.
Regularly, I need to perform a search inside that IList<Node>
, which I do as follows:
List_of_Nodes.Where(o => o.Name == "Something").FirstOrDefault();
I would like to know if there is a way to speed that up.
In a database, a search within a table can be executed faster by creating an index on the column you want to search on.
Is that also possible in a C# IList
?
(I've been looking on the site, but I always get results like List_of_Nodes[index]
. It would be great it I could replace the search by List_of_Nodes[name]
, but how can I achieve that?
答案1
得分: 6
根据每个键是否存在重复,您可以使用Dictionary<TKey, TValue>
(或带有自定义比较器的HashSet):
表示键和值的集合。
var indexByName = nodeList.ToDictionary(n => n.Name);
// 或者
var indexByName = nodeList
.GroupBy(n => n.Name)
.ToDictionary(g => g.Key, g => g.First()); // 或 g => g.ToArray()
通过索引器按键访问值(如果不存在,则会引发异常),或者使用TryGetValue
方法。
表示每个键映射到一个或多个值的集合。
Lookup<TKey, TElement>
类似于Dictionary<TKey, TValue>
。不同之处在于,Dictionary<TKey, TValue>
将键映射到单个值,而Lookup<TKey, TElement>
将键映射到值的集合。
var indexByName = nodeList.ToLookup(node => node.Name);
使用索引器通过key
访问数据,如果在集合中找不到key
,则返回空序列。
注意:
- 这两者都可以被视为哈希索引的等价物,要模拟其他类型的索引(如B-Tree),您需要使用其他数据结构。
- 这两种
To...
方法都允许指定比较器,例如,要支持不区分大小写的比较,可以使用nodeList.ToLookup(n => n.Name, StringComparer.OrdinalIgnoreCase)
。
英文:
Depending on the presence of duplicates per key you can use Dictionary<TKey,TValue>
(or hashset with custom comparer):
> Represents a collection of keys and values.
var indexByName = nodeList.ToDictionary(n => n.Name);
// or
var indexByName = nodeList
.GroupBy(n => n.Name)
.ToDictionary(g => g.Key, g => g.First()); // or g => g.ToArray()
And access the value by key via indexer (will throw if not present) or via TryGetValue
method.
or Lookup<TKey,TElement>
:
> Represents a collection of keys each mapped to one or more values.
> A Lookup<TKey,TElement>
resembles a Dictionary<TKey,TValue>
. The difference is that a Dictionary<TKey,TValue>
maps keys to single values, whereas a Lookup<TKey,TElement>
maps keys to collections of values.
var indexByName = nodeList.ToLookup(node => node.Name);
And use indexer to access the data by key
, if the key
is not found in the collection, an empty sequence is returned.
Notes:
-
Both can be considered as equivalent of Hash indexes, to simulate other types of indexes (like B-Tree) you will need to use other data structures.
-
Both
To...
methods allows to specify comparer, for example to support case insensitive comparison -nodeList.ToLookup(n => n.Name, StringComparer.OrdinalIgnoreCase)
答案2
得分: 3
你可以尝试使用Dictionary
作为索引(类似于数据库中的哈希索引);让它是Dictionary<string, Node[]>
:对于给定的Key
,我们会得到相应Node
的数组:
// 基于 Dictionary 构建索引
var myIndex = List_of_Nodes
.GroupBy(node => node.Name)
.ToDictionary(group => group.Key, group => group.ToArray());
...
// 询问索引是否有名称为 "Something" 的节点...
var result = myIndex.TryGetValue("Something", out var nodes)
? nodes[0] // ... 如果有,获取第一个节点
: null;
英文:
You can try using Dictionary
as an index (which is similar to hash index in a database); let it be Dictionary<string, Node[]>
: for given Key
we get an array of corresponding Node
s:
// Build Dictionary based index
var myIndex = List_of_Nodes
.GroupBy(node => node.Name)
.ToDictionary(group => group.Key, group => group.ToArray());
...
// Ask index if it has nodes with "Something" Name...
var result = myIndex.TryGetValue("Something", out var nodes)
? nodes[0] // ... if it has, obtain the 1st one
: null;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论