【问题标题】:Shift all values of Dictionary to a new key将 Dictionary 的所有值转移到新键
【发布时间】:2016-07-11 22:29:57
【问题描述】:

我有一个通用字典,它为我的基于网格的游戏的地图中的每个坐标存储 Tile 定义。

Dictionary<IntVector2, Tile> tiles;

使用此设置可以任意调整地图大小,因为只需添加新坐标即可,无需更改任何其他内容。但是,我想使用 (0,0) 坐标作为地图枢轴进行其他计算,这需要我能够在创建地图后更改地图中心坐标。

是否有一种更简洁、更高效的方法将字典中的所有值(平铺)转移到新坐标,必要时创建新键,然后删除所有未使用的键?

到目前为止,我有这个:

public void MovePivot(int xDelta, int yDelta)
{
    // Copy my existing tile map.
    Dictionary<IntVector2, Tile> tilesCopy = new Dictionary<IntVector2, Tile>(tiles);

    // Initialize a new empty one.
    tiles = new Dictionary<IntVector2, Tile>();

    // Copy all old values into the new one, but shift each coordinate.
    foreach (var tile in tilesCopy)
    {
        IntVector2 newKey = tile.Key + new IntVector2(xDelta, yDelta);
        tiles.Add(newKey, tile.Value);
    }
}

如果不复制我的字典,这是否可能“就地”?

【问题讨论】:

  • 可能无论如何都不安全,除非您可以保证“移动”键的行为不会产生与现有键重叠的键。
  • 创建一个包装 Dictionary 并私下维护当前 x,y 偏移量的类是否可行?然后字典元素永远不需要移动。相反,在每次访问字典时,当前的偏移量都会被透明地应用。
  • 是的,这是可能的。我看到的唯一缺点是,它给系统增加了一点点复杂性,因为我需要确保为每个更改图块的方法正确应用偏移量。此外,断点处的调试信息可能会稍微难以解释。
  • 如果您按照@crokusek 的建议将字典包装到另一个类中,并且不将内部字典暴露给外界,则可以保持简单。
  • @crokusek 请提供建议的答案。

标签: c# dictionary


【解决方案1】:

可以实现一种新的字典类型,保留当前班次的记忆并在读/写期间执行班次。

示例用法:

AdjustableDictionary<int, string> map = new AdjustableDictionary<int, string>((key, adj) => key + adj);

这应该很接近。值与引用类型可能存在问题。

public class AdjustableDictionary<K, V> 
{
    public K CurrentAdjustment { get; set; }        
    public int Count { get { return _dictionary.Count; } }
    public ICollection<K> Keys { get { return _dictionary.Keys.Select(k => AdjustKey(k)).ToList(); } }

    private IDictionary<K, V> _dictionary;
    private Func<K, K, K> _adjustKey;

    public AdjustableDictionary(Func<K, K, K> keyAdjuster = null)
    {
        _dictionary = new Dictionary<K, V>();
        _adjustKey = keyAdjuster;
    }

    public void Add(K key, V value)
    {
        _dictionary.Add(AdjustKey(key), value);
    }

    public bool ContainsKey(K key)
    {
        return _dictionary.ContainsKey(AdjustKey(key));
    }

    public bool Remove(K key)
    {
        return _dictionary.Remove(AdjustKey(key));
    }

    public bool TryGetValue(K key, out V value)
    {
        return _dictionary.TryGetValue(AdjustKey(key), out value);
    }

    public ICollection<V> Values { get { return _dictionary.Values; } }

    public V this[K key] {
        get {
            return _dictionary[AdjustKey(key)];
        }
        set {
            _dictionary[AdjustKey(key)] = value;
        }
    }

    public void Clear()
    {
        _dictionary.Clear();
    }

    private K AdjustKey(K key)
    {
        return _adjustKey != null
            ? _adjustKey(key, CurrentAdjustment)
            : key;
    }
}

上面的代码大部分是从这个VirtualDictionary answer修改的

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 2011-02-17
    • 2016-07-03
    相关资源
    最近更新 更多