Как запросить словарь C # и вернуть определенный набор значений - PullRequest
3 голосов
/ 22 февраля 2012

В моей программе на C # есть словарь, который содержит список Key + Values.

Значения itemid, Month, Year, Count

Я бы хотел запросить словарь, сравнив набор значений (itemid, Month, Year) и вернув true или false, если конкретный itemid + Month + Year существует.

Таким образом, если все 3 значения (itemid + Month + Year) существуют, верните true, иначе верните false.

Я пробовал что-то вроде этого

(if (myd.Select(d => d.Value.itemid == item.itemid && d.Value.Month == DateRange.Month  && d.Value.Year == DateRange.Year).ToString() != "")

Выше не сработало.

Ответы [ 5 ]

3 голосов
/ 22 февраля 2012

Вы, похоже, неправильно поняли использование метода Select (). Select создает «проекцию»; учитывая входную коллекцию (перечисляемую) элементов, она создает перечисляемую выходную информацию, равную по мощности, но состоящую из элементов, каждый из которых является результатом преобразования соответствующего элемента ввода.

Вам нужен либо метод Where () (который возвращает список, меньший или равный по мощности количеству входных данных, элементов из входных данных, для которых выполняется булево условие), либо метод Any () ( который возвращает единственное «истина» или «ложь», если какой-либо из элементов на входе удовлетворяет условию):

if(myd.Where(d => d.Value.itemid == item.itemid 
                && d.Value.Month == DateRange.Month 
                && d.Value.Year == DateRange.Year).Count() >= 1)
   ...

//produces the equivalent result but generally performs faster
if(myd.Any(d => d.Value.itemid == item.itemid 
                && d.Value.Month == DateRange.Month 
                && d.Value.Year == DateRange.Year))
   ...
1 голос
/ 22 февраля 2012

Если подобен синтаксису linq, он проверяет, существует ли хотя бы один элемент, удовлетворяющий всем трем условиям:

if((from d in myd
where d.Value.itemid == item.itemid
&& d.Value.Month == DateRange.Month
&& d.Value.Year == DateRange.Year).FirstOrDefault() != null)
0 голосов
/ 22 февраля 2012

Если вы работаете с .NET 4.0, вы можете использовать кортежи в качестве ключей.

var dict = new Dictionary<Tuple<int,int,int>,MyValueType>();

Затем вы можете проверить, существует ли значение с

var key = new Tuple<int,int,int>(item.itemid, DateRange.Month, DateRange.Year);
if(dict.ContainsKey(key)) {
   ...
}

Или вы можете проверить

if(dict.ContainsValue(referenceValue)) {
    ...
}

Вам нужно будет передать ему справочное значение, содержащее то, что вы ищете.Убедитесь, что ваш тип значения реализует EqualityComparer<T>.

Первый метод будет намного быстрее, так как доступ к словарю осуществляется с помощью ключа.Если вы не получаете доступ к словарю по ключу, вы также можете использовать List<T>.

0 голосов
/ 22 февраля 2012

использовать Куда фильтровать (я предполагаю, что условие в вашем коде определено правильно ... вы не дали нам достаточно информации, чтобы оценить это)

var filteredDictionary = myd.Where(d => d.Value.itemid == item.itemid && d.Value.Month == DateRange.Month  && d.Value.Year == DateRange.Year)

используйте Выбрать для преобразования изKeyValuePair для значения

var filteredValues = filteredDictionary.Select(x=>x.Value)

используйте Any для возврата логического значения того, существует ли элемент

bool matchExists = myd.Any(d => d.Value.itemid == item.itemid && d.Value.Month == DateRange.Month  && d.Value.Year == DateRange.Year)

Any и будет наиболее эффективным для описываемой вами проблемы.потому что он прекратит оценивать элементы в словаре и вернет True, как только совпадение будет найдено

0 голосов
/ 22 февраля 2012

Вам нужно будет создать второй словарь, если вы хотите выполнять поиск с другим ключом (в данном случае itemid, месяц, год, возможно, помещенный в кортеж), и вам нужно будет поддерживать их оба при каждом добавлении/ удалить из любого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...