.NET 3.5 之前的字典中的 ElementAt 方法

本文关键字:字典 ElementAt 方法 NET | 更新日期: 2023-09-27 18:37:26

我有一个使用 ElementAt() 方法的Dictionary<int, DataRow>。 它在 .NET 3.5 及更高版本中运行良好。 但是,我的ISP似乎正在运行一些不理解该方法 pre-.NET 3.5版本,从而出现以下错误:

编译器错误消息: CS0117: 'System.Collections.Generic.Dictionary<int,System.Data.DataRow>' 不包含 'ElementAt' 的定义

我需要使用 ElementAt 的原因是因为我想选择随机字典元素,然后删除该元素,直到所有元素都随机显示

                int key = testimonialDictionary.ElementAt(rnd).Key;
... do something with the Value / DataRow
                testimonialDictionary.Remove(key);

我的问题是,人们在 ElementAt() 之前使用什么? 我该如何实现?

.NET 3.5 之前的字典中的 ElementAt 方法

我相信

这将是实现它的简单方法

string ElementAt(Dictionary<string,string> dict, uint index)
{   
    if(dict.Count > index)
    {
        uint iCnt =0;
        foreach(KeyValuePair<string,string> val in dict)
        {
            if(index == iCnt)
                return val.Key;
            iCnt++;
            if(index < iCnt)
               return null;
       }
   }
   return null;
}

测试它

Dictionary<string,string> dict = new Dictionary<string,string>{{"A","1"},{"B","2"},{"C","3"},{"D","4"},{"E","5"}};
for(uint i=0;i<5;i++)
    Console.WriteLine(ElementAt(dict,i));

基于您希望以随机顺序获取所有字典元素的事实

我想随机选择字典元素,然后删除该元素,直到所有元素都随机显示

。一次得到一个键的答案最终是 O(n^2),因为取出一个键是 O(n),你必须做 O(n) 次。

这就是我的做法:

  1. 将所有字典键放入数组中。这在 LINQ 之前仍然是可能的,但我确实必须查找它!
var keys = new int[testimonialDictionary.Count];
testimonialDictionary.Keys.CopyTo(keys, 0);
  1. 对键数组执行费舍尔-耶茨洗牌,以将键按随机顺序排列。
var r = new Random();
for (int i = keys.Length - 1; i > 0; i--)
{
    var putIntoI = r.Next(i + 1);
    var temp = keys[putIntoI];
    keys[putIntoI] = keys[i];
    keys[i] = temp;
}
  1. 以这种随机顺序遍历键,根据需要显示它们,并(如果您确实需要)将它们也从字典中删除。
for (int i = 0; i < keys.Length; i++)
{
    // Display the key and/or its corresponding value
    Display(keys[i], testimonialDictionary[keys[i]]);
    // Remove the item from the dictionary if you have to
    testimonialDictionary.Remove(keys[i]);
}

我们采用更多的python风格怎么样:

int key = testimonialDictionary.Keys.ToArray()[rnd];
testimonialDictionary.Remove(key);

确保您的 rnd 不大于您拥有的密钥数减去 1 或小于 0!!

更新:正如索蒙指出的那样,.ToArray() 也是 linq,所以改用这个:

int i = 0;
int? key = null
foreach(int k in testimonialDictionary.Keys){
    if(i==rnd){
        key = k;
        break;
    }
    i++;
}
testimonialDictionary.Remove(key)

(可惜你不能使用.3.5 中的 skip()