我应该使用什么数据结构?

发布于 2024-12-11 19:41:07 字数 2298 浏览 4 评论 0原文

我有一个问题,我需要将两个输入映射到一个输出。

我知道字典是通用类型的线性映射:

对于每个 x(key),可能有 ay(value

我需要的是多维映射:

对于每个 x,y(key),可能有 az(value

但当然最重要的是我需要它支持通用类型并动态调整大小。

C# 中是否存在此数据结构,或者我是否必须创建字典的字典?如果没有必要,我宁愿不重新发明轮子。


重新发明轮子:

using System;
using System.Collections.Generic;
using System.Text;

namespace zlib.Collections
{
    public class Dictionary3D<Tx, Ty, Tz>
    {
        private Dictionary<Tuple<Tx, Ty>, Tz> _dict = new Dictionary<Tuple<Tx, Ty>, Tz>();

        public void Add(Tx x, Ty y, Tz z)
        {
            _dict.Add(Tuple.Create<Tx, Ty>(x, y), z);
        }

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

        public bool ContainsKey(Tx x, Ty y)
        {
            return _dict.ContainsKey(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool ContainsValue(Tz z)
        {
            return _dict.ContainsValue(z);
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.Enumerator GetEnumerator()
        {
            return _dict.GetEnumerator();
        }

        public bool Remove(Tx x, Ty y)
        {
            return _dict.Remove(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool TryGetValue(Tx x, Ty y, out Tz z)
        {
            return _dict.TryGetValue(Tuple.Create<Tx, Ty>(x, y), out z);
        }

        public int Count
        {
            get { return _dict.Count; }
        }

        public Dictionary<Tuple<Tx,Ty>,Tz>.KeyCollection Keys
        {
            get
            {
                return _dict.Keys;
            }
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.ValueCollection Values
        {
            get
            {
                return _dict.Values;
            }
        }

        public Tz this[Tx x, Ty y]
        {
            get
            {
                return _dict[Tuple.Create<Tx, Ty>(x, y)];
            }
            set
            {
                _dict[Tuple.Create<Tx, Ty>(x, y)] = value;
            }
        }
    }
}

似乎重新发明轮子在回应中胜出。这是我到目前为止想出的代码,但我觉得应该有更好的方法,比如矩阵之类的。

I have an issue where I need to map two inputs to a single output.

I'm aware that a dictionary is a generically typed linear mapping:

for every x (key) there may be a y (value)

What I need is a multi-dimensional mapping:

for every x,y (key) there may be a z (value)

But of course the kicker is that I need it to support generic typing and be dynamically sized.

Does this data-structure exist in C#, or do I have to create a dictionary of dictionaries? I'd rather not reinvent the wheel if I don't have to.


Reinventing the wheel:

using System;
using System.Collections.Generic;
using System.Text;

namespace zlib.Collections
{
    public class Dictionary3D<Tx, Ty, Tz>
    {
        private Dictionary<Tuple<Tx, Ty>, Tz> _dict = new Dictionary<Tuple<Tx, Ty>, Tz>();

        public void Add(Tx x, Ty y, Tz z)
        {
            _dict.Add(Tuple.Create<Tx, Ty>(x, y), z);
        }

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

        public bool ContainsKey(Tx x, Ty y)
        {
            return _dict.ContainsKey(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool ContainsValue(Tz z)
        {
            return _dict.ContainsValue(z);
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.Enumerator GetEnumerator()
        {
            return _dict.GetEnumerator();
        }

        public bool Remove(Tx x, Ty y)
        {
            return _dict.Remove(Tuple.Create<Tx, Ty>(x, y));
        }

        public bool TryGetValue(Tx x, Ty y, out Tz z)
        {
            return _dict.TryGetValue(Tuple.Create<Tx, Ty>(x, y), out z);
        }

        public int Count
        {
            get { return _dict.Count; }
        }

        public Dictionary<Tuple<Tx,Ty>,Tz>.KeyCollection Keys
        {
            get
            {
                return _dict.Keys;
            }
        }

        public Dictionary<Tuple<Tx, Ty>, Tz>.ValueCollection Values
        {
            get
            {
                return _dict.Values;
            }
        }

        public Tz this[Tx x, Ty y]
        {
            get
            {
                return _dict[Tuple.Create<Tx, Ty>(x, y)];
            }
            set
            {
                _dict[Tuple.Create<Tx, Ty>(x, y)] = value;
            }
        }
    }
}

It seems like reinventing the wheel is winning out among responses. This is the code I've come up with so far, but I feel like there should be a better way, like a matrix or something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

为人所爱 2024-12-18 19:41:07

又怎么样

   Dictionary<Tuple<T,K>,Tuple<L,J>> 

what about

   Dictionary<Tuple<T,K>,Tuple<L,J>> 

??

古镇旧梦 2024-12-18 19:41:07

如果我没理解错的话,这就是您所需要的:

class Key<Tx, Ty>
{
    public Tx x;
    public Ty y;

    public Key(Tx x, Ty y)
    {
        this.x = x;
        this.y = y;
    }
}

Dictionary<Key<Tx, Ty>, Tz> d;

是的,评论中提到的,您必须在该 Key 类中实现 HashCode 和 Equals。

If I get you right, that is what you need:

class Key<Tx, Ty>
{
    public Tx x;
    public Ty y;

    public Key(Tx x, Ty y)
    {
        this.x = x;
        this.y = y;
    }
}

Dictionary<Key<Tx, Ty>, Tz> d;

And yes, how mentioned in a comment, you gotta implement HashCode and Equals in that Key class.

め七分饶幸 2024-12-18 19:41:07

如果您使用 Tuple,Chuck Jazdzewski 不久前写的 PolyDictionary 可能会满足您的需求。作为钥匙。实际上,它只是 Dictionary的包装器。但这确实有效。查看他有关该主题的博客系列:

The PolyDictionary that Chuck Jazdzewski wrote about awhile back might get you what you want if you use a Tuple<T1, T2> as the key. Really, it's just a wrapper around a Dictionary<object, object> but it does the trick. Check out his blog series on the topic:

忆依然 2024-12-18 19:41:07

Tuple 可能是您想要的:

var population = new Tuple< string, int>("New York", 7891957);

或者对于泛型:

var population = new Tuple< S, T>("New York", 7891957);

对于 Tuple 参考一下 这里

此外,如果您想要字典的用户字典,您可以这样做:

using DictOfDict = Dictionary< X, Dictionary< Y, Z>> ;

作为参考,请查看 此处

Tuple is probably what you want:

var population = new Tuple< string, int>("New York", 7891957);

or for generics:

var population = new Tuple< S, T>("New York", 7891957);

For Tuple a reference look here

Moreover, if you want for example user Dictionary of a Dictionary you can do like this:

using DictOfDict = Dictionary< X, Dictionary< Y, Z>> ;

For a reference look here

携君以终年 2024-12-18 19:41:07

怎么样:

class Dict3D
{
    private Dictionary<KeyValuePair<object,object>, object> innnerDict= new Dictionary<KeyValuePair<object,object>, object>();

    public object Get(object key1, object key2)
    {
        KeyValuePair<object,object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            return innnerDict[bigKey];
        }
        return null;
    }

    public void Set(object key1, object key2, object somevalue)
    {
        KeyValuePair<object, object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            innnerDict[bigKey] = somevalue;
        }
        else
        {
            innnerDict.Add(bigKey, somevalue);
        }
    }
}

您也可以将其设为通用,但这是一个简单的版本。

我想答案意味着如果你想要一个干净的解决方案,你(或其他人)可能必须重新发明轮子。

How about this:

class Dict3D
{
    private Dictionary<KeyValuePair<object,object>, object> innnerDict= new Dictionary<KeyValuePair<object,object>, object>();

    public object Get(object key1, object key2)
    {
        KeyValuePair<object,object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            return innnerDict[bigKey];
        }
        return null;
    }

    public void Set(object key1, object key2, object somevalue)
    {
        KeyValuePair<object, object> bigKey = new KeyValuePair<object, object>(key1, key2);
        if (innnerDict.ContainsKey(bigKey))
        {
            innnerDict[bigKey] = somevalue;
        }
        else
        {
            innnerDict.Add(bigKey, somevalue);
        }
    }
}

You could make it a generic also, but this is a simple version.

I guess the answers mean that if you want a clean solution, you (or someone else) probably does have to reinvent the wheel.

狼性发作 2024-12-18 19:41:07

我认为您将需要一个类型安全的异构容器,它由字典支持。在这种情况下,您将必须重写 IDictionary 并拥有自己的实现。不幸的是,除非您遵循其他答案或找到解决办法,否则没有您可以使用的课程。

参见Joshua bloch 在这种情况下,你基本上可以存储任何类型作为键。但是您也可以限制它。

I think you will need a type safe heterogeneous container, which is backed by a dictionary. In this case, you will have to override IDictionary and have your own impl. Unfortunately there is no class that you can use unless you follow other answers or find a work around i guess.

See Joshua bloch in this case, you can basically store any type as the key. however you can restrict that as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文