【问题标题】:Is there anything that implements a fast random access list in C#?有什么可以在 C# 中实现快速随机访问列表的吗?
【发布时间】:2012-09-04 11:04:26
【问题描述】:

我找到了OrderedDictionary,但它并没有达到我想要的效果。 OrderedDictionary 似乎呈现数据的字典或列表视图,但您不能很好地在它们之间进行交叉。

例如

OrderedDictionary mylist = new OrderedDictionary();

mylist.Add(1, "Hello");
mylist.Add(4, "World");
mylist.Add(7, "Foo");
mylist.Add(9, "Bar");

使用此代码,我可以直接访问mylist[7] 并获取"Foo",也可以按正确的顺序遍历内容,但我无法快速回答“列表中的Foo 后面是什么?”这个问题。

我想要的是这样的:

mylist.GetNode(7).Next.Value => "Bar"

.NET 和 C# 中是否有任何可用的东西可以执行此任务?

【问题讨论】:

  • 注:mylist[7] 不会尝试返回 OrderedDictionary 中的第 7 项,而不是带有键 7 的条目? (OrderedDictinoary 同时拥有 objectint 索引器:-/)
  • 我也有类似的问题stackoverflow.com/questions/8157140/…
  • @Rawling - 好点。这里的 int 是一个索引。为了争论,我们可以假设我将密钥包装在一个很好的可比较对象中。

标签: c# .net list dictionary hashtable


【解决方案1】:

为什么不能只在索引中添加一个?

mylist[3] == "Foo";
mylist[3 + 1] == "Bar";

如果数据结构支持随机访问,我看不出你为什么要添加链表样式的行为。

编辑

似乎OrderedDictionary 可以使用索引和键see MSDN

否则,您可以很容易地添加自己的“下一步”指针:

class DictionaryNode {
  public int? Next { get; set; }
  public string Value { get; set; }
}


// Inside the appropriate class
int? lastKey = null;

void AddItem(int key, string value) {
  mylist.Add(key, new DictionaryNode { Next = null, Value = value });
  if (lastKey.HasValue) {
    mylist[lastKey].Next = key;
  }
  lastKey = key;
}

【讨论】:

  • 假设顺序是随机的,但是是升序的。我会更新Q
  • 顺序如何随机升序?
  • 我认为他的意思是密钥是随机的,但顺序是升序的。
  • 是的,@RonWarholic 说的。
【解决方案2】:

使用SortedList类(是的,我们必须击败那个叫SortedList这个名字的家伙)。

static class SortedListExtensions
{
    public static TValue GetNextValueOrDefault<TKey, TValue>(this SortedList<TKey, TValue> list, TKey key)
    {
        var indexOfKey = list.IndexOfKey(key);

        if (indexOfKey == -1)
            return default(TValue);

        if (++indexOfKey == list.Count)
            return default(TValue);

        return list.Values[indexOfKey];
    }
}

var myList = new SortedList<int, string>
{
    { 1, "Hello" },
    { 4, "World" },
    { 7, "Foo" },
    { 9, "Bar" },
};

Console.WriteLine(myList.GetNextValueOrDefault(7)); // "Bar"
Console.WriteLine(myList.GetNextValueOrDefault(9)); // null

【讨论】:

  • 具体使用IndexOfKey然后Values[i + 1]?此外,如果合适,the generic version 会更好。
  • @Rawling:谢谢,我错过了一个链接。更新了代码示例。
  • 看起来 .NET 4.5 还有一个 GetByIndex 方法
【解决方案3】:

丑陋,但你可以像这样即时进行:

OrderedDictionary mylist = new OrderedDictionary(); 
mylist.Add(1, "Hello"); 
mylist.Add(4, "World"); 
mylist.Add(7, "Foo"); 
mylist.Add(9, "Bar");

int key = 7;
Console.WriteLine("value: " + mylist[key as object]);
var nextKeys = mylist.Keys.Cast<int>().Where(i => i > key);
if (nextKeys.Count() == 0)
    Console.WriteLine("next value: (none)");
else
    Console.WriteLine("next value: " + mylist[nextKeys.Min() as object]);

【讨论】:

    猜你喜欢
    • 2021-01-12
    • 2017-05-07
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2012-05-10
    相关资源
    最近更新 更多