C #: Использование хэш-таблиц для хранения двух одинаковых значений. Является ли это возможным?

Я новичок в программировании на C #, и я написал программу, которая использует хэш-таблицы для хранения данных (в моем случае имя пользователя, и если они «Готовы» или «Не готовы». Всего у меня 2 таблицы. в первой таблице указан ключ в качестве имени пользователя и IP-адрес клиента в поле значения. Во второй таблице указано состояние «Готов / не готов» (указанное в поле со списком) для ключа и IP-адрес в качестве значения.

Первая таблица не проблема, так как я не хочу, чтобы имя пользователя повторялось. Однако во второй таблице мне нужно, чтобы статус «Готов / не готов» повторялся много раз. Однако это не работает, поскольку в хеш-таблице уже есть ключ под названием «Готов». Есть ли способ обойти это?


person Alex Godbehere    schedule 15.10.2010    source источник


Ответы (5)


Вы можете использовать Dictionary<Status,HashSet<IP>> для второй таблицы. Это имеет дополнительное преимущество в том, что вставка / удаление IP происходит быстро, поскольку это ключ в HashSet.

person CodesInChaos    schedule 15.10.2010
comment
Хотя для различения значений двойного статуса (Готов / Не готов) словарь на самом деле кажется излишним. - person Dirk Vollmar; 16.10.2010
comment
Поскольку он говорил о поле со списком, а не о флажке, я не был уверен, есть ли более двух состояний. Если есть только два состояния, тогда использование двух HashSet (по одному для каждого статуса) определенно будет предпочтительнее. - person CodesInChaos; 16.10.2010
comment
Да, всего 2 состояния. В основном у меня есть 3 значения для каждого пользователя (IP-адрес, имя пользователя, состояние готовности / неготовности). Есть ли способ отобразить поле значения хеш-таблицы вместо ключа? - person Alex Godbehere; 16.10.2010

Итак, вторая хеш-таблица нужна для того, чтобы быстро узнать, кто готов или нет, правильно?

В этом случае подумайте о том, чтобы разделить это на две разные коллекции: одну для тех, кто готов, и одну для тех, кто не готов.

Скорее всего, здесь подойдет простой List ‹T›, поскольку вам просто нужно увидеть, кто там находится, а не искать конкретного (потому что, если вы хотите это сделать, вы можете просто посмотреть в другой хеш-таблице). Если важно иметь свойства поиска, похожие на хэш-таблицу, вы можете использовать HashSet ‹T › вместо этого, но это зависит от ваших потребностей.

person Michael Madsen    schedule 15.10.2010
comment
Кроме того, я предполагаю, что под хеш-таблицей вы подразумеваете концепцию, а не обязательно HashTable - в большинстве случаев это Словарь - лучший выбор из-за безопасности типа. - person Michael Madsen; 16.10.2010

Ключи должны быть уникальными. Если бы вы попытались получить доступ к значению по ключу, как бы он узнал, какое из них вам действительно нужно?

person Dismissile    schedule 15.10.2010

Похоже, что Hashtable, вероятно, не идеальная структура данных для вашей проблемы.

Ключи в хэш-таблице / словаре должны быть уникальными, поэтому нет, вы не можете технически хранить две записи в хэш-таблице, которые имеют один и тот же ключ.

Кроме того, вам, вероятно, следует использовать Dictionary<TKey, TValue) вместо фактического типа Hashtable, поскольку он имеет лучшие характеристики производительности.

Вы можете смоделировать то, что хотите, сделав что-то вроде создания словаря, значение которого представляет собой какой-то набор:

// Map containing two sets of IP addresses: those that are ready, 
// and those that are not ready.
var readyMap = new Dictionary<bool, HashSet<string>>();
readyMap[true] = new HashSet<string>();
readyMap[false] = new HashSet<string>();

// Add an IP address that is ready.
readyMap[true].Add(ipAddress1);

// Add an IP address that is not ready.
readyMap[false].Add(ipAddress2);

Однако это может быть не идеальным решением. Какую проблему вы пытаетесь решить?

person mtreit    schedule 15.10.2010
comment
По сути, то, что я пытаюсь создать, - это решение, очень похожее на систему Ready Up в играх, которая уведомляет хост, если пользователи готовы начать игру. Стоит ли размещать код для серверной и клиентской программ? - person Alex Godbehere; 16.10.2010
comment
Я не думаю, что вам нужно публиковать свой код для всех программ. Думаю, есть несколько способов решить эту проблему. Другой подход, который вы можете рассмотреть, - иметь один набор адресов Not Ready, который изначально содержит всех. Когда машина переходит в состояние «готово», вы просто удаляете ее из набора «не готов». Когда набор пуст, все готовы. HashSet ‹T› снова является хорошим выбором для этого. - person mtreit; 16.10.2010
comment
Хорошо, я наконец понял это. У меня 3 стола. Первый - Ключ: Значение имени пользователя: IP. Во-вторых, ключ: значение IP: имя пользователя. Третий ключ: значение имени пользователя: готов / не готов. Затем я просто ссылаюсь на htReady.Value (хеш-таблицу). Здесь весь мой код: pastebin.com/Z60GEjK8. Части, на которые вы хотите обратить внимание, являются началом Классы ChatServer, AddUser, RemoveUser и AcceptClient. - person Alex Godbehere; 16.10.2010

Хорошо, я наконец понял это. У меня 3 стола. Первый - Ключ: Значение имени пользователя: IP. Во-вторых, ключ: значение IP: имя пользователя. В-третьих, ключ: значение имени пользователя: готов / не готов. Затем я просто ссылаюсь на htReady.Value (хеш-таблицу). Здесь весь мой код: http://pastebin.com/Z60GEjK8. Вы хотите увидеть начало классов ChatServer, AddUser, RemoveUser и AcceptClient.

Я новичок в этом, поэтому, если вы можете предложить лучший способ, я весь уши.

person Alex Godbehere    schedule 15.10.2010