← Назад к вопросам
Для чего нужна структура данных словарь?
1.3 Junior🔥 181 комментариев
#Коллекции и структуры данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Dictionary в C# и Unity
Dictionary (словарь) — это неупорядоченная коллекция пар ключ-значение, которая обеспечивает быстрый поиск, добавление и удаление элементов по ключу. Это одна из самых полезных структур данных в программировании.
Основные характеристики
1. Структура ключ-значение
Каждый элемент в Dictionary состоит из ключа и связанного с ним значения:
Dictionary<string, int> scores = new Dictionary<string, int>();
// Ключ: "Alice", Значение: 100
scores.Add("Alice", 100);
// Ключ: "Bob", Значение: 85
scores["Bob"] = 85;
// Получение значения по ключу
int aliceScore = scores["Alice"]; // 100
2. Быстрый поиск (O(1))
Dictionary использует хеширование для быстрого доступа к элементам:
Dictionary<int, string> items = new Dictionary<int, string>();
items[1] = "Sword";
items[2] = "Shield";
items[3] = "Potion";
// Быстрый поиск — O(1) в среднем случае
string weapon = items[1]; // Sword
// VS List — нужно итерировать O(n)
List<string> itemList = new List<string> { "Sword", "Shield", "Potion" };
string found = itemList.FirstOrDefault(x => x == "Sword"); // Медленнее
Практические применения в Unity
Пример 1: Система инвентаря
public class Inventory : MonoBehaviour
{
// Ключ: ID предмета, Значение: количество
private Dictionary<int, int> items = new Dictionary<int, int>();
public void AddItem(int itemId, int quantity = 1)
{
if (items.ContainsKey(itemId))
{
items[itemId] += quantity; // Увеличить количество
}
else
{
items[itemId] = quantity; // Добавить новый предмет
}
}
public int GetItemCount(int itemId)
{
if (items.ContainsKey(itemId))
{
return items[itemId];
}
return 0;
}
public void RemoveItem(int itemId, int quantity = 1)
{
if (items.ContainsKey(itemId))
{
items[itemId] -= quantity;
if (items[itemId] <= 0)
{
items.Remove(itemId);
}
}
}
}
Пример 2: Система способностей
public class AbilitySystem : MonoBehaviour
{
// Ключ: название способности, Значение: способность
private Dictionary<string, Ability> abilities = new Dictionary<string, Ability>();
public void RegisterAbility(string name, Ability ability)
{
abilities[name] = ability;
}
public void CastAbility(string abilityName)
{
if (abilities.ContainsKey(abilityName))
{
abilities[abilityName].Cast();
}
else
{
Debug.LogError($"Ability {abilityName} not found!");
}
}
}
Пример 3: Система уровней
public class LevelManager : MonoBehaviour
{
// Ключ: ID уровня, Значение: данные уровня
private Dictionary<int, LevelData> levels = new Dictionary<int, LevelData>();
private void LoadLevels()
{
levels[1] = new LevelData { name = "Forest", difficulty = 1 };
levels[2] = new LevelData { name = "Castle", difficulty = 2 };
levels[3] = new LevelData { name = "Dragon Lair", difficulty = 3 };
}
public LevelData GetLevel(int levelId)
{
// Try-else для безопасного доступа
if (levels.TryGetValue(levelId, out LevelData levelData))
{
return levelData;
}
return null;
}
}
Пример 4: Кэширование
public class ResourceCache : MonoBehaviour
{
// Ключ: путь к ресурсу, Значение: загруженный объект
private Dictionary<string, GameObject> cachedPrefabs = new Dictionary<string, GameObject>();
public GameObject GetPrefab(string path)
{
// Если уже загружено, вернуть из кэша
if (cachedPrefabs.ContainsKey(path))
{
return cachedPrefabs[path];
}
// Загрузить и кэшировать
GameObject prefab = Resources.Load<GameObject>(path);
if (prefab != null)
{
cachedPrefabs[path] = prefab;
}
return prefab;
}
}
Основные методы
Dictionary<string, int> dict = new Dictionary<string, int>();
// Добавление
dict.Add("key", 10);
dict["key2"] = 20; // Проще и безопаснее
// Получение
int value = dict["key"]; // Исключение, если ключа нет
dict.TryGetValue("key", out int value); // Безопаснее
// Проверка наличия
bool hasKey = dict.ContainsKey("key");
bool hasValue = dict.ContainsValue(10);
// Удаление
dict.Remove("key");
dict.Clear(); // Очистить всё
// Итерация
foreach (var kvp in dict) // KeyValuePair
{
Debug.Log($"{kvp.Key}: {kvp.Value}");
}
foreach (var key in dict.Keys)
{
Debug.Log(key);
}
foreach (var value in dict.Values)
{
Debug.Log(value);
}
// Размер
int count = dict.Count;
Безопасный доступ
// ❌ ОПАСНО — может выбросить исключение
int value = dict["nonexistent"]; // KeyNotFoundException
// ✅ БЕЗОПАСНО — использовать TryGetValue
if (dict.TryGetValue("key", out int value))
{
Debug.Log($"Value: {value}");
}
else
{
Debug.Log("Key not found");
}
// ✅ Альтернатива с ContainsKey
if (dict.ContainsKey("key"))
{
int value = dict["key"];
}
Производительность
// List — O(n) для поиска
List<Item> items = new List<Item>();
Item found = items.FirstOrDefault(x => x.id == 5); // Медленно!
// Dictionary — O(1) для поиска
Dictionary<int, Item> itemDict = new Dictionary<int, Item>();
itemDict.TryGetValue(5, out Item found); // Быстро!
Типы ключей
// Строки
Dictionary<string, string> config = new Dictionary<string, string>();
// Числа
Dictionary<int, Player> players = new Dictionary<int, Player>();
// Enum
enum ItemType { Weapon, Armor, Potion }
Dictionary<ItemType, int> itemCounts = new Dictionary<ItemType, int>();
// Пользовательские типы (должны переопределить GetHashCode и Equals)
Dictionary<Vector3, Tile> tileMap = new Dictionary<Vector3, Tile>();
Когда использовать Dictionary
✅ Используй Dictionary когда:
- Нужен быстрый поиск по ключу (O(1))
- Работаешь с парами ключ-значение
- Нужен кэш или хранилище конфигов
- Реализуешь системы инвентаря или карты
❌ Не используй Dictionary когда:
- Нужно сохранить порядок элементов (используй List)
- Нужны частые итерации всех элементов (List может быть быстрее)
- Нужна отсортированность (используй SortedDictionary)
Dictionary — это неотъемлемая часть арсенала каждого программиста!