如何获取Dictionary元素的相对位置?

时间:2010-09-22 15:16:40

标签: c# c#-4.0

我有下一个C#代码:

    Dictionary<string, int> d = new Dictionary<string, int>();
    d.Add("a", 3);
    d.Add("b", 1);
    d.Add("c", 0);
    d.Add("d", -1);
    d.Add("e", -9);

当搜索键“c”时,我想得到这个键的位置,即2.如果我找到键“e”,我想得到4.如果找不到元素,相对位置可能是-1

添加了: 除非你有更好的想法,否则我想填充一个矩阵,其中包含由找到的字典元素的相对位置指示的行号中的某些值。这同样适用于列但使用不同的字典。一个例子:

     n4   n2   n1   n3  n9  . . . 
a   4/4
b              2         8
c
d                  8/2
e         4/3
.
.
.

其中a,b,c,d,e,...是字典“d”的键,n4,n2,n3,n9是第二个字典的键。

我怎么能得到这个?

5 个答案:

答案 0 :(得分:9)

Dictionary<,>中没有“位置”这样的东西 - 它是一个无序的集合。

按键分类的类似集合 - SortedList<,>SortedDictionary<,>。请注意,这些是按键排序而不是插入时间。目前尚不清楚你想要的是什么。

答案 1 :(得分:1)

字典没有隐含的键值对顺序。如果你需要“位置”,你使用的方式是错误的。

在编辑中:如果要实现矩阵,最好的办法是使用多维数组。例如:

int[,] matrix = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };

等同于以下矩阵:

1 2
3 4
5 6

您可以使用matrix[i][j]访问其元素;例如matrix[0][0]为1,matrix[0][1]为2,等等。

答案 2 :(得分:1)

这应该可以解决问题:

d.Keys.ToList().IndexOf("c");

请注意,字典提供的O(1)时间查找在转换为List时会丢失,因为列表本质上是O(n)。因此,如果您的词典中包含大量元素,那么最好使用另一个词典或矩阵维度来存储位置,因为以这种方式检索它们可能会更慢。实际上,您应该假设上面的单行类似于:

GetDictKeyPos(d, "c");

public int GetDictKeyPos(Dictionary<string, int> d, string key)
{
    for (int i = 0; i < d.Count; ++i)
    {
        if (d.ElementAt(i).Key == key)
            return i;
    }
    return -1;
}

作为旁注,如果您想要获得该位置,您可能会假设该位置被保留。微软表示不要指望它,但在实践中你会发现你可能依赖它。 (我从来没有看到过被保留的位置。)话虽如此,直到微软承认,“是的,是的,我们一直坚持你:位置实际上保存在字典中。我们只是不想承认它,因为我们希望能够改变它,如果我们找到了更好的实现,但现在我们知道我们将离开它,所以在这里,你去......“,你可能不应该假设这个位置被保留。

最后,如果您计划抓住机会并假设它已被保留,并且您还计划使用上述方法获取位置,那么请考虑将密钥存储在List中,因为查找时间将相同,保证列表顺序保留。

答案 3 :(得分:0)

您将无法使用任何内置集合数据结构,包括KeyedCollection。但是,您可以通过从Collection派生并在内部包含Dictionary来快速查找密钥,轻松创建自己的集合类。 Collection类本身提供了索引检索的功能。

public class KeyValueCollection<TKey, TValue> : Collection<KeyValuePair<TKey, TValue>>
{
    private Dictionary<TKey, TValue> m_Dictionary = new Dictionary<TKey, TValue>();

    public TValue GetValue(TKey key)
    {
        return m_Dictionary[key];
    }

    public void Add(TKey key, TValue value)
    {
        m_Dictionary.Add(key, value);
        base.Add(new KeyValuePair<TKey, TValue>(key, value));
    }

    protected override void ClearItems()
    {
        m_Dictionary.Clear();
        base.ClearItems();
    }

    protected override void InsertItem(int index, KeyValuePair<TKey, TValue> item)
    {
        m_Dictionary.Add(item.Key, item.Value);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {

        m_Dictionary.Remove(this[index].Key);
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, KeyValuePair<TKey, TValue> item)
    {
        m_Dictionary[this[index].Key] = item.Value;
        base.SetItem(index, item);
    }
}

答案 4 :(得分:-1)

如果您真的在寻找这种功能,为什么不维护辅助数据结构,以维持添加元素的顺序

(OR)

可能你只想维护一个存储

的结构列表
   [{"a",-1},{"b",1},{"c",0},{"d",-1},{"e",-9}]