c # словарь один ключ много значений - PullRequest
61 голосов
/ 20 января 2010

Я хочу создать хранилище данных, чтобы позволить мне хранить некоторые данные.

Первая идея состояла в том, чтобы создать словарь, в котором у вас есть 1 ключ со многими значениями, поэтому он немного похож на отношение один ко многим.

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

Как еще можно хранить эту информацию?

Ответы [ 13 ]

0 голосов
/ 03 ноября 2017

Вы можете создать очень упрощенный много словарь, который автоматизирует процесс вставки значений следующим образом:

public class MultiDictionary<TKey, TValue> : Dictionary<TKey, List<TValue>>
{
    public void Add(TKey key, TValue value)
    {
        if (TryGetValue(key, out List<TValue> valueList)) {
            valueList.Add(value);
        } else {
            Add(key, new List<TValue> { value });
        }
    }
}

Это создает перегруженную версию метода Add. Исходный позволяет вставить список элементов для ключа, если запись для этой записи еще не существует. Эта версия позволяет вставить один элемент в любом случае.

0 голосов
/ 26 октября 2017

Вы также можете использовать;

 List<KeyValuePair<string, string>> Mappings;
0 голосов
/ 22 августа 2017

Вот мой подход к достижению такого поведения.

Для более полного решения, включающего ILookup<TKey, TElement>, посмотрите мой другой ответ .

public abstract class Lookup<TKey, TElement> : KeyedCollection<TKey, ICollection<TElement>>
{
  protected override TKey GetKeyForItem(ICollection<TElement> item) =>
    item
    .Select(b => GetKeyForItem(b))
    .Distinct()
    .SingleOrDefault();

  protected abstract TKey GetKeyForItem(TElement item);

  public void Add(TElement item)
  {
    var key = GetKeyForItem(item);
    if (Dictionary != null && Dictionary.TryGetValue(key, out var collection))
      collection.Add(item);
    else
      Add(new List<TElement> { item });
  }

  public void Remove(TElement item)
  {
    var key = GetKeyForItem(item);
    if (Dictionary != null && Dictionary.TryGetValue(key, out var collection))
    {
      collection.Remove(item);
      if (collection.Count == 0)
        Remove(key);
    }
  }
}

Использование:

public class Item
{
  public string Key { get; }
  public string Value { get; set; }
  public Item(string key, string value = null) { Key = key; Value = value; }
}

public class Lookup : Lookup<string, Item>
{
  protected override string GetKeyForItem(Item item) => item.Key;
}

static void Main(string[] args)
{
  var toRem = new Item("1", "different");
  var single = new Item("2", "single");
  var lookup = new Lookup()
  {
    new Item("1", "hello"),
    new Item("1", "hello2"),
    new Item(""),
    new Item("", "helloo"),
    toRem,
    single
  };

  lookup.Remove(toRem);
  lookup.Remove(single);
}

Примечание: ключ должен быть неизменным (или извлекаться и повторно добавляться при смене ключа).

...