【问题标题】:Getting from a dictionary with int[] arrays as value [duplicate]从具有 int[] 数组作为值的字典中获取 [重复]
【发布时间】:2015-07-07 03:01:09
【问题描述】:

我有以下代码

public Dictionary<int[], string> worldMap = new Dictionary<int[], string>();

for (int x=0; x <= 10; x++) {
    for (int y=0; y <= 10; y++) {
        int[] cords = new int[]{x,y};
        worldMap.Add(cords, "empty");          
    }
}

如何从这本字典中获取值?

【问题讨论】:

  • 世界地图[new int[]{1,1}]
  • 你不能把 Dictionary 改成 Dictionary 吗?
  • 我尝试了 Debug.Log(worldmap(new int[]{1,1})),但它不允许我运行它。当我尝试 Debug.Log[worldmap(new int[]{1,1})] 时,它说找不到密钥
  • 不,我不能,我特别需要它,所以我不能在字典中输入坐标,它会给我那个区域的地形类型

标签: c#


【解决方案1】:

创建一个IEqualityComparer 并使用它定义您的字典。您可以在下面的 SO 问题中找到示例代码:

An integer array as a key for Dictionary

【讨论】:

    【解决方案2】:

    您可以遍历整个字典。

    foreach (var map in worldMap)
    {
        Console.WriteLine(String.Join(", ", map.Key) + " - " + map.Value);
    }
    

    或者通过参考查找

    Dictionary<int[], string> worldMap = new Dictionary<int[], string>();
    
    for (int x = 0; x <= 10; x++)
    {
        for (int y = 0; y <= 10; y++)
        {
            int[] cords = new int[] { x, y };
            worldMap.Add(cords, "empty");
    
            Console.WriteLine(worldMap[cords]);
        }
    }
    

    当您使用数组或类时,字典使用对后台对象的引用。这使得一些事情变得不可能。例如,如果您使用相同的值新建另一个列表,则字典将抛出异常,说明未找到该键。

    Dictionary<int[], string> worldMap = new Dictionary<int[], string>();
    
    for (int x = 0; x <= 10; x++)
    {
        for (int y = 0; y <= 10; y++)
        {
            int[] cords = new int[] { x, y };
            worldMap.Add(cords, "empty");
    
            //This will cause an exception
            Console.WriteLine(worldMap[new int[] { x, y }]);
        }
    }
    

    【讨论】:

    • 使用类并不完全正确——你可以使用正确覆盖GetHashCodeEquals的类,只要哈希码发生变化,即只读对象。这就是String 类的工作方式。匿名类也是如此。
    【解决方案3】:

    考虑使用 System.Drawing.Point 而不是 int 数组。通常,只有与进入其中的对象完全相同,字典才会匹配。即使是另一个具有相同值的对象也不起作用。

    但是某些数据类型(例如 Point)是不同的,它们实现了在字典中使用键所必需的所有哈希和相等检查功能。

    【讨论】:

      【解决方案4】:

      填充世界地图后,您可以获得这样的密钥(您必须添加using System.Linq):

      List<int[]> coords = worldMap.Keys.ToList();
      

      然后您可以像这样从坐标List 获取任何值(确保您使用的值在List 的范围内):

      worldMap[coords[0]]
      

      代码示例:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      
      public class Program
      {
          public static void Main()
          {
              Dictionary<int[], string> worldMap = new Dictionary<int[], string>();
              for (int x = 0; x <= 10; x++)
              {
                  for (int y = 0; y <= 10; y++)
                  {
                      int[] cords = new int[] { x, y };
                      worldMap.Add(cords, String.Format("empty{0}_{1}", x, y));
                  }
              }
              // This should have 121 coordinates from (0, 0) to (10, 10)
              List<int[]> coords = worldMap.Keys.ToList();
              Console.WriteLine(worldMap[coords[21]]);
          }
      }
      

      Demo

      【讨论】:

        【解决方案5】:

        int[] 用于您的文字地图坐标是一个糟糕的选择,原因有很多,尤其是当您似乎特别使用时,我可以发送零、一、三个或更多值只有两个。

        您最好创建自己的只读类来保存您的坐标。

        试试这个课程:

        public sealed class WorldMapCoord : IEquatable<WorldMapCoord>
        {
            private readonly int _X; 
            private readonly int _Y;
        
            public int X { get { return _X; } } 
            public int Y { get { return _Y; } }
        
            public WorldMapCoord(int X, int Y)
            {
                _X = X; 
                _Y = Y;    
            }
        
            public override bool Equals(object obj)
            {
                if (obj is WorldMapCoord)
                        return Equals((WorldMapCoord)obj);
                return false;
            }
        
            public bool Equals(WorldMapCoord obj)
            {
                if (obj == null) return false;
                if (!EqualityComparer<int>.Default.Equals(_X, obj._X)) return false; 
                if (!EqualityComparer<int>.Default.Equals(_Y, obj._Y)) return false;    
                return true;
            }
        
            public override int GetHashCode()
            {
                int hash = 0;
                hash ^= EqualityComparer<int>.Default.GetHashCode(_X); 
                hash ^= EqualityComparer<int>.Default.GetHashCode(_Y);
                return hash;
            }
        
            public override string ToString()
            {
                return String.Format("{{ X = {0}, Y = {1} }}", _X, _Y);
            }
        }
        

        现在您的代码将如下所示:

        public Dictionary<WorldMapCoord, string> worldMap = new Dictionary<WorldMapCoord, string>();
        
        for (int x=0; x <= 10; x++)
        {
            for (int y=0; y <= 10; y++)
            {
                worldMap.Add(new WorldMapCoord(x, y), "empty");          
            }
        }
        

        由于该类是只读的,并且它实现了GetHashCodeEquals,您可以使用此代码从字典中检索值:

        for (int x=0; x <= 10; x++)
        {
            for (int y=0; y <= 10; y++)
            {
                string value = worldMap[new WorldMapCoord(x, y)];
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-03
          • 1970-01-01
          • 2016-08-26
          • 2017-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-09
          相关资源
          最近更新 更多