← Назад к вопросам

Для чего нужна структура данных словарь?

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 — это неотъемлемая часть арсенала каждого программиста!