Hashtable с несколькими значениями для одного ключа - PullRequest
11 голосов
/ 29 декабря 2010

Я хочу сохранить несколько значений в одном ключе, например:

HashTable obj = new HashTable();
obj.Add("1", "test");
obj.Add("1", "Test1");

Сейчас это приводит к ошибке.

Ответы [ 11 ]

8 голосов
/ 29 декабря 2010

вы можете поместить свой test,test1,test2,... в таблицу, а затем поместить эту таблицу в Hashtable как значение для ключа, который будет одинаковым для всех них.

Например попробуйте что-то вроде этого:

List<string> list = new List<string>();
list.Add("test");
list.Add("test1"); 

и затем:

HashTable obj = new HashTable();
obj.Add("1", list);
6 голосов
/ 29 декабря 2010

Нельзя использовать один и тот же ключ в словаре / хэш-таблице. Я думаю, что вы хотите использовать список для каждого ключа, например (VB.NET):

Dim dic As New Dictionary(Of String, List(Of String))
Dim myValues As New List(Of String)
myValues.Add("test")
myValues.Add("Test1")
dic.Add("1", myValues)

C #:

Dictionary<string, List<string>> dic = new Dictionary<string, List<string>>();
List<string> myValues = new List<string>();
myValues.Add("test");
myValues.Add("Test1");
dic.Add("1", myValues);
4 голосов
/ 29 декабря 2010

Я использую свой собственный MultiDictionary класс. Он основан на Dictionary<TKey,List<TValue>>, но предлагает немного синтаксического сахара поверх этого. Должно быть легко реализовать Entry<TValue> для реализации IList<T>

public class MultiDictionary<TKey, TValue>
{
    private Dictionary<TKey, List<TValue>> data = new Dictionary<TKey, List<TValue>>();

    public struct Entry : IEnumerable<TValue>
    {
        private readonly MultiDictionary<TKey, TValue> mDictionary;
        private readonly TKey mKey;

        public TKey Key { get { return mKey; } }

        public bool IsEmpty
        {
            get
            {
                return !mDictionary.data.ContainsKey(Key);
            }
        }

        public void Add(TValue value)
        {
            List<TValue> list;
            if (!mDictionary.data.TryGetValue(Key, out list))
                list = new List<TValue>();
            list.Add(value);
            mDictionary.data[Key] = list;
        }

        public bool Remove(TValue value)
        {
            List<TValue> list;
            if (!mDictionary.data.TryGetValue(Key, out list))
                return false;
            bool result = list.Remove(value);
            if (list.Count == 0)
                mDictionary.data.Remove(Key);
            return result;
        }

        public void Clear()
        {
            mDictionary.data.Remove(Key);
        }

        internal Entry(MultiDictionary<TKey, TValue> dictionary, TKey key)
        {
            mDictionary = dictionary;
            mKey = key;
        }

        public IEnumerator<TValue> GetEnumerator()
        {
            List<TValue> list;
            if (!mDictionary.data.TryGetValue(Key, out list))
                return Enumerable.Empty<TValue>().GetEnumerator();
            else
                return list.GetEnumerator();
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public Entry this[TKey key]
    {
        get
        {
            return new Entry(this, key);
        }
    }
}
1 голос
/ 08 августа 2014

Возможно, это 4 года спустя, но я надеюсь, что это кому-нибудь поможет позже.Как упоминалось ранее в посте, невозможно использовать тот же ключ для различных значений в Hashtable (ключ, значение).Хотя вы можете создать List или некоторый объект в качестве значения в паре ключ / значение HashTable.

//instantiate new Hashtable
Hashtable hashtable = new Hashtable();

//create a class that would represent a value in the HashTable
public class SomeObject
{
    public string value1 { get; set;}
    public string value2 { get; set;}
}

//create a List that would store our objects
List<SomeObject> list = new List<someObject>();

//add new items to the created list
list.Add(new SomeObject() 
             { 
                 value1 = "test", 
                 value2 = "test1"
             });
list.Add(new SomeObject() 
             {
                 value1 = "secondObject_value1" 
                 value2 = "secondObject_value2"
             })

//add key/value pairs to the Hashtable.
hashTable.Add("1", list[0]);
hashTable.Add("2", list[1]);

Затем, чтобы получить эти данные:

//retrieve the value for the key "1"
SomeObject firstObj = (SomeObject)hashTable[1];
//retrieve the value for the key "2"
SomeObject secondObj = (SomeObject)hashTable[2];
Console.WriteLine("Values of the first object are: {0} and {1}", 
                                             firstObj.value1,firstObj.value2);
Console.WriteLine("Values of the second object are {0} and {1}",
                                             secondObj.value1, secondObj.value2);
// output for the WriteLine:
Values of the first object are: test and test1
Values of the second object are secondObject_value1 and secondObject_value2
1 голос
/ 29 декабря 2010

Это приводит к ошибке, потому что вы добавляете один и тот же ключ дважды. Попробуйте использовать Dictionary вместо HashTable.

Dictionary<int, IList<string>> values = new Dictionary<int, IList<string>>();
IList<string> list = new List<string>()
{
    "test", "Test1"
};
values.Add(1, list);
1 голос
/ 29 декабря 2010

Вы можете использовать словарь.

На самом деле, то, что вы только что описали, является идеальным использованием для коллекции словарей.Он должен содержать пары ключ: значение независимо от типа значения.Сделав значение своим собственным классом, вы сможете легко расширить его в будущем, если возникнет такая необходимость.

Пример кода:

class MappedValue
{
    public string SomeString { get; set; }
    public bool SomeBool { get; set; }
}

Dictionary<string, MappedValue> myList = new Dictionary<string, MappedValue>;
0 голосов
/ 20 сентября 2013

Было бы лучше, если бы вы использовали две хеш-таблицы, как я использовал в этой библиотеке

0 голосов
/ 13 июня 2013

Вы можете использовать NameValueCollection - работает так же, как hashtable и имеет «GetValues ​​()».

0 голосов
/ 29 декабря 2010

JFYI, вы можете объявить свой диск следующим образом:

Dictionary<int, IList<string>> dic = new
{
    { 1, new List<string> { "Test1", "test1" },
    { 2, new List<string> { "Test2", "test2" }
};
0 голосов
/ 29 декабря 2010

Вы ищете Lookup , который может изначально хранить несколько значений для каждого ключа.

Как указывалось, это работает только для фиксированного списка, поскольку вы не можете добавлять записи вищите, как только вы его создали.

public class LookupEntry
{
    public string Key { get; set; }
    public string Value { get; set; }
}

var list = new List<LookupEntry>(new LookupEntry [] 
                                    {
                                    new LookupEntry() {Key="1", Value="Car" }, 
                                    new LookupEntry() {Key="1", Value="Truck"},
                                    new LookupEntry() {Key="2", Value="Duck"}
                                    });


var lookup = list.ToLookup(x => x.Key, x => x.Value);
var all1s = lookup["1"].ToList();
...