将数组转换为字典,其中value作为项的索引,key作为项本身

本文关键字:索引 key value 数组 转换 字典 其中 | 更新日期: 2023-09-27 18:02:40

我有一个数组,如-

arr[0] = "Name";
arr[1] = "Address";
arr[2] = "Phone";
...

我想创建一个Dictionary<string, int>,这样数组值将是字典键,字典值将是索引,这样我就可以通过查询O(1)中的列的名称来获得列的索引。我知道这应该很简单,但是我就是想不明白。

I tried -

Dictionary<string, int> myDict = arr.ToDictionary(x => x, x => indexOf(x))
但是,这返回-
{(Name, 0), (Address, 0), (Phone, 0),...}

我知道这会发生,因为它存储了第一次出现的索引,但这不是我想要做的。

将数组转换为字典,其中value作为项的索引,key作为项本身

您可以使用Select的过载,其中包括索引:

var dictionary = array.Select((value, index) => new { value, index })
                      .ToDictionary(pair => pair.value, pair => pair.index);

或使用Enumerable.Range:

var dictionary = Enumerable.Range(0, array.Length).ToDictionary(x => array[x]);

注意,如果您尝试提供两个相等的键,ToDictionary将抛出异常。你应该仔细考虑数组中有两个相等值的可能性,以及在这种情况下你希望发生什么。

我很想手动操作:

var dictionary = new Dictionary<string, int>();
for (int i = 0; i < array.Length; i++)
{
    dictionary[array[i]] = i;
}

var dictionary = arr.ToDictionary(x => Array.IndexOf(arr, x));

我做了一些基准测试,因为在我的场景中性能和分配很重要。下面是我最后使用的:

var dictionary = new Dictionary<T, int>(array.Length);
for (var i = 0; i < array.Length; i++)
    dictionary[array[i]] = i;
技巧是设置初始容量以减少字典数据结构内部的重新分配。对比结果见下表(越少越好,基线设置为@Jon Skeet第一个答案):
<表类>比例 Alloc比率tbody> <<tr> Preallocate td> 0.27 Manual for loop0.48 0.73 可点数的。范围0.63 0.78 选择(元组)1.0 0.78 选择(匿名类型)1.0 1.0 tbody>