【问题标题】:c# reading all entries of the same value in dictionary/c# 读取字典中相同值的所有条目/
【发布时间】:2012-06-12 23:38:52
【问题描述】:

C# 新手。 我正在尝试制作一个简单的系统,我可以在其中搜索对象列表以及它何时属于某个 ID。把它放在一个 List/ArrayList 中,这样我就可以读出来/做其他任何事情。

每个“项目”都有一个 locationID。当我进入这个位置并按“看”。程序应该检查我在哪个位置,只取出具有相同 ID 的“项目”。

在实践中。项目列表将非常大(以及位置)。因此,一次又一次地浏览列表似乎是一种浪费。这就是我想用字典的原因。但我似乎无法访问字典中的多个条目,只能在一个特定位置访问。

例如:

Dictionary<string, int> itemLoc = new Dictionary<string, int>();
itemLoc.Add("pen", 011);
itemLoc.Add("paper", 011);
itemLoc.Add("tv remote", 012);

//print everything in location 011

抱歉,缺少代码。我仍在想办法解决这个问题。我一直在研究 ArrayLists、Lists、Hashtables 和这些字典。但是没有一个,我已经能够有效地实现我正在寻找的东西。

我可以做一个 foreach 并检查每个条目。但就像上面提到的。这似乎是对处理的浪费。

任何想法或提示? 非常感谢您在代码方面朝着正确的方向轻推。

【问题讨论】:

  • 您是否有理由不将这些保存在数据库中并在那里进行查询 - 这似乎是一个合理的解决方案(并且可能更容易长期维护)。

标签: c# dictionary


【解决方案1】:

您正在做的是将整数值存储在您正在使用的字符串键的哈希指定的位置。

一个更好的主意是使用Dictionary&lt;int, List&lt;string&gt;&gt;(或任何 C# 为列表类提供的),当您在某个位置添加第一项时执行itemLoc.Add(011, new List&lt;string&gt;()); itemLoc.Get(011).Add("pen"); 之类的操作(因此您想检查是否该位置首先作为字典中的键存在),然后只是itemLoc.Get(011).Add("paper");

请注意,我的语法可能不正确,因为我自己没有使用过 C#,但应该不会有那么大的不同。如果 C# 字典类有一个AddIfAbsent()-type 方法,那将有助于简化我提到的键检查。

【讨论】:

    【解决方案2】:

    您没有就您的问题的限制向我们提供足够的信息。 Dictionary&lt;string, List&lt;string&gt;&gt; 的执行速度会更快,但您尚未确定是否可以在多个位置拥有多个项目(例如,“纸张”可以在 011 和 012 中还是仅在 011 中?)在这种情况下,每次添加您必须确保该项目尚未在其他位置。

    一种非常简单的方法是非常简单地将其分解,并根据您的结果进行优化。

    class MyItem
    {
        public string Name { get; set; }
        public string Location { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            List<MyItem> myItems = new List<MyItem>()
            {
                new MyItem() { Location = "011", Name = "pen" },
                new MyItem() { Location = "011", Name = "paper" },
                new MyItem() { Location = "012", Name = "tv remote" }
            };
    
            var specificItems = myItems.Where(f => f.Location == "011");
    
            foreach (var item in specificItems)
            {
                Console.WriteLine(item.Name);
            }
    
            Console.Read();
        }
    }
    

    执行基准测试后,您可以考虑将其转换为某种东西(可能是Dictionary&lt;string, List&lt;string&gt;&gt;

    【讨论】:

    • 是的,每个对象同时只能在一个地方。当位置数量将超过 20 并且项目将超过 400 时,这是否足够高效/快速以每分钟执行多次?
    • @TwanMul:这太小了。在这种情况下,它应该足够快供您使用。您可以使用Stopwatch 类执行一些基本的基准测试。
    【解决方案3】:

    根据定义,字典的每个键都有一个值。您不能使用一个键访问多个值。

    但是,您可以使用 List 作为值。因此,如果您想在同一位置创建一组项目并在以后重用它,您可以将其存储在 key 为 locationID 的字典中:Dictionary>

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      Dictionary 提供映射值,但不是相反。您可以构建另一个字典,其中位置 ID 作为键,项目集合作为值,并以这种方式查找位置 ID

      【讨论】:

        【解决方案5】:

        字典可以让您有效地根据位置找到项目,或者让您有效地根据项目找到位置,但不能两者兼而有之。 (这并不是说以另一种方式执行它并不是非常低效,只是效率更低,通常是 O(n),而不是更快。)

        所以,您有几种可能性。最简单的方法就是遍历itemLoc.Values 并寻找你想要的。更复杂的是维护第二个集合,Dictionary&lt;int, List&lt;string&gt;&gt;,它将存储每个位置的整个项目列表。这将使查找变得非常快速和容易,但代价是维护数据(插入、更新、删除)的工作量更大。

        这完全取决于您要优化的内容。在最极端的情况下,您可以放弃Dictionary&lt;string,int&gt; 并专门使用Dictionary&lt;int, List&lt;string&gt;&gt;,在您需要查找某个项目的位置时进行搜索——但您只想在这种查找类型为非常罕见。

        【讨论】:

          【解决方案6】:

          推荐

          Dictionary<int, List<string>>
          

          这样您可以在每个位置添加多个项目

          例如

          var locItems = new Dictionary<int, List<string>>();
          
          List<string> items = new List<string>() { "item1", "Item2", "item3" };
          
          locItems.Add(1, items);
          
          // Get all items from location 1 ...
          List<string> items = locItems[1];
          
          foreach(string s in items)
              Console.WriteLine(s);
          
          // Now add another item to the list
          items.Add("Some new item");
          
          // Since this is by ref - the list in the dict will be modified 
          // so you don't need to worry about re-adding it to the dict
          

          【讨论】:

          • 感谢您的回复!一个小菜鸟问题。 var locItems : var 是否意味着我可以选择我自己的 var,或者这就是你写的方式?对于第一个,你会推荐哪个 var。
          • var 只是一个隐式类型变量声明 - 即使用推断类型。你可以写 string mystring = "bob",或者你可以写 var mystring = "bob"。这两者等同于同一件事,因为将值“bob”分配给变量会推断出变量的类型是字符串。您可以更改行 List items = locItems[1];到 var items = locItems[1];因为 locItems[1] 会返回一个 List ,因此“items”的类型会从用法中推断出来
          【解决方案7】:

          代码现在的样子,您只能拥有一支笔、一张纸等。这是因为您将它们用作字典的键。完成这项任务的更好方法是拥有一个

          Dictionary&lt;int, List&lt;string&gt;&gt;

          int 是房间 ID(001、011 等),列表是存储在每个房间中的对象。给定房间 ID,您现在可以遍历该房间中存储的所有物品的列表。

          【讨论】:

            猜你喜欢
            • 2016-08-27
            • 1970-01-01
            • 2023-02-23
            • 1970-01-01
            • 2013-07-17
            • 2021-11-24
            • 1970-01-01
            • 2016-02-09
            • 1970-01-01
            相关资源
            最近更新 更多