是否在 C# List 上可以实现 “数据库索引”?

huangapple go评论61阅读模式
英文:

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>

表示每个键映射到一个或多个值的集合。
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&lt;TKey,TValue&gt;(or hashset with custom comparer):

> Represents a collection of keys and values.

var indexByName = nodeList.ToDictionary(n =&gt; n.Name);
// or 
var indexByName = nodeList
   .GroupBy(n =&gt; n.Name)
   .ToDictionary(g =&gt; g.Key, g =&gt; g.First()); // or g =&gt; g.ToArray()

And access the value by key via indexer (will throw if not present) or via TryGetValue method.

or Lookup&lt;TKey,TElement&gt;:

> Represents a collection of keys each mapped to one or more values.
> A Lookup&lt;TKey,TElement&gt; resembles a Dictionary&lt;TKey,TValue&gt;. The difference is that a Dictionary&lt;TKey,TValue&gt; maps keys to single values, whereas a Lookup&lt;TKey,TElement&gt; maps keys to collections of values.

var indexByName = nodeList.ToLookup(node =&gt; 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 =&gt; 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&lt;string, Node[]&gt;: for given Key
we get an array of corresponding Nodes:

// Build Dictionary based index
var myIndex = List_of_Nodes
  .GroupBy(node =&gt; node.Name)
  .ToDictionary(group =&gt; group.Key, group =&gt; group.ToArray());

...

// Ask index if it has nodes with &quot;Something&quot; Name...
var result = myIndex.TryGetValue(&quot;Something&quot;, out var nodes)
  ? nodes[0] // ... if it has, obtain the 1st one
  : null;

huangapple
  • 本文由 发表于 2023年4月19日 18:19:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76053351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定