Класс .NET для быстрого определения значения на основе ключа и наоборот - PullRequest
2 голосов
/ 28 сентября 2010

Очень часто я использую тип Dictionary<TKey, TValue> для хранения значений типа словаря, например. Key = 1, Value ="Canada". Но во многих случаях значения в данных словаря также уникальны, как и ключи. И я считаю, что для типа Dictionary<TKey, TValue> не очень удобно получать значение ключа на основе значения.

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

Ответы [ 4 ]

4 голосов
/ 28 сентября 2010

Это довольно тривиально, используя LINQ:

int key = new Dictionary<int,string>().Where((kv)=>kv.Value == "SomeValue").Select(kv=>kv.Key).FirstOrDefault();

И метод расширения, если вам нравится:

static class DictionaryExtensions {
    public static bool TryFindByValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, TValue value, out TKey key) {
        var keys = dict.Where((kv) => kv.Value.Equals(value)).Select(kv => kv.Key);
        bool retValue = keys.Any();
        key = keys.FirstOrDefault();
        return retValue;
    }
}

Также вы можете реализовать IDictionary, делегировать два Dictionary объекта (один для сопоставления ключ-значение и один для сопоставления ключ-значение) для резервного хранилища и иметь ограничение на Add, что значения Должно быть уникальным. Таким образом, вы гарантируете, что будет не более одной записи с определенным значением. РЕДАКТИРОВАТЬ Использование двух словарей улучшит время доступа (спасибо @SamStephens), так как ключи и значения будут храниться в упорядоченной хеш-таблице.

2 голосов
/ 28 сентября 2010

Не думайте, что есть что-то, что поставляется с .NET. Там, вероятно, сторонний класс. Но вы можете очень легко создать свой собственный класс, который содержит два словаря, один с обратными ключами и значениями.

1 голос
/ 28 сентября 2010

(требуется .NET 4.0)

var list = new List<Tuple<int, string>>
{
 new Tuple<int, string>(1, "Canada"),
 new Tuple<int, string>(2, "USA")
};

var i = list.FirstOrDefault(t => t.Item1 == 1);
var j = list.FirstOrDefault(t => t.Item2 == "USA");
0 голосов
/ 28 сентября 2010

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

(
 from x in dict.Values
 where x.Prop == "someValue"
 select x
)
.FirstOrDefault()

ИЛИ просто

dict.Values.FirstOrDefault(x => x.Prop == "someValue");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...