Я хочу добиться следующего. Словарь вроде структуры данных, который я инициализирую с помощью var m = new MultiMap<string, int, bool>();
, а затем я должен иметь доступ к нему, используя m[string1]
или m[int1]
, а string1 - это строка, а int1 - это int. Конечно, если мне нужно добавить значение, мне нужно будет сделать что-то вроде этого m.add(string2, int2, bool2)
, так что оба ключа не равны нулю. Есть ли что-то подобное уже имеющееся? Спасибо и приветствую!Словарь с несколькими ключевыми типами
ответ
У вас просто не может быть двух ключей для предмета. Когда вы добавляете элемент в словарь с ключом и значением, внутренний хэш-код этого ключа генерируется путем вызова метода GetHashCode этого ключа, и значение сохраняется с этим хеш-кодом. Поэтому, если вы можете каким-то образом сопоставить свои строки и int ключи с тем же хэш-кодом, то только вы сможете получить доступ к своему значению с помощью любого из одного ключа. Поэтому, если это возможно, то лучше всего реализовать класс Key с тремя конструкциями, один для строки, один для int и один для обоих. Затем реализуем IEqualityComparer, передайте его в конструкцию словаря.
Вы можете свернуть свой собственный довольно быстро, так что здесь является частично законченный класс: (. Я думал, что я дам вам немного форы, и вы можете взять его здесь)
public class MultiKeyDictionary<T>
{
private Dictionary<int, T> _indexDictionary = new Dictionary<int, T>();
private Dictionary<string, T> _keyDictionary = new Dictionary<string, T>();
public int Count
{
get { return _indexDictionary.Count; }
}
public T this[string key]
{
get
{
T result;
if (!TryGetValue(key, out result))
{
throw new IndexOutOfRangeException();
}
return result;
}
set
{
throw new NotImplementedException();
}
}
public T this[int key]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public void Add(int index, string key, T value)
{
_indexDictionary.Add(index, value);
_keyDictionary.Add(key, value);
}
public void Clear()
{
_indexDictionary.Clear();
_keyDictionary.Clear();
}
public bool Contains(T item)
{
return _indexDictionary.ContainsValue(item);
}
public bool Remove(string key)
{
throw new NotImplementedException();
}
public bool Remove(int key)
{
throw new NotImplementedException();
}
public bool TryGetValue(string key, out T value)
{
var result = _keyDictionary.TryGetValue(key, out value);
return result;
}
public bool TryGetValue(int key, out T value)
{
var result = _indexDictionary.TryGetValue(key, out value);
return result;
}
}
После этого вы можете:
var m = new MultiKeyDictionary<bool>();
m.add(int2, string2, bool2)
и доступ к ней нравится:
var mystring = m[string1];
var myint = m[int1];
Хотя Я фанат оборонительного программирования и, как правило, используют TryGetValue()
методы:
bool value;
if (m.TryGetValue(string1, out value))
{
// value exists, I don't get an IndexOutOfRangeException
}
bool value;
if (m.TryGetValue(int1, out value))
{
// value exists, I don't get an IndexOutOfRangeException
}
List <Кортеж>() должны делать то, что вы хотите. Вы можете LINQ выбрать/where клаузулы для Item1 (String), Item2 (Int32) и Item3 (Boolean). –
См. Http://stackoverflow.com/q/689940/2076784 и http://stackoverflow.com/q/1171812/2076784. – gpaoli
Я бы просто пошел на реализацию с двумя базовыми словарями, если у вас нет ограничений памяти. –