Приведение списка результатов LINQ KeyValuePair в словарь - отсутствует концепция - PullRequest
6 голосов
/ 31 декабря 2010

Я хотел написать это утверждение LINQ:

Dictionary<int, ItemBO> result = ( Dictionary<int, ItemBO> )
    ( from item in originalResults where item.Value.SomeCriteria == true
    select item );

originalResults имеет тип Dictionary<int, ItemBO>.

Я понял, что item имеет тип KeyValuePair<int, ItemBO>, номог бы подумать, что приведение из списка этого типа к словарю этого типа было бы ... э ... "естественным".

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

Dictionary<int, ItemBO> result = 
    ( from item in originalResults where item.Value.SomeCriteria == true
    select item.Value ).ToDictionary( GetItemKey );

Что, хотя и не совсем нелогично, наводит на мысль, что под обложками происходит много ненужной работы по распаковке и переупаковке Словаря.Есть ли лучшее решение?Есть ли концепция, по которой я упускаю?

Ответы [ 4 ]

4 голосов
/ 31 декабря 2010

Что, хотя и не совсем нелогично, наводит на мысль о том, что под обложками идет много ненужной работы по распаковке и переупаковке Словаря.

Я не уверен, что вы подразумеваете под "ненужной" работой. Для выполнения этой операции требуется много работы - ваш запрос должен быть полностью оценен, что включает сканирование всего словаря и оценку предиката для каждой записи. Кроме того, новый словарь должен быть создан и заполнен для хранения результатов. Я думаю, что было бы больше проблем, если бы эта работа была скрыта автоматическим преобразованием.

Настоящая проблема в том, что вы используете свой словарь в обратном направлении. Поиск по ключу быстрый, но поиск по значению требует сканирования всех элементов в словаре. Если бы вы могли хранить словарь так, чтобы значение, которое вы используете для фильтрации, было ключевым, то вы сможете выполнять гораздо более быстрые поиски и с более чистым синтаксисом.

2 голосов
/ 31 декабря 2010

Я собираюсь сделать еще один удар по тому, что реальный"ключевой" концепт, который вам не хватает, это

Если бы я рискнул предположить, я бы сказал, что я думаю вы представляете Dictionary<TKey, TValue> как синоним его содержимого. У вас есть пара пар ключ-значение - это словарь, верно? И здесь вы упускаете важную деталь.Хотя вы, конечно, могли бы реализовать IDictionary<TKey, TValue>, используя, скажем, простой KeyValuePair<TKey, TValue>[], в этом случае было бы упущено одно из величайших преимуществ наличия словарного типа в первую очередь: быстрый поиск по ключу.

Даже если вы сохраняете массив отсортированным и используете бинарный поиск для определения местоположения ключей (что, кстати, потребует затрат на все вставки), вы не сможете конкурировать с реализацией хеш-таблицы что Dictionary<TKey, TValue> использует.Эта реализация не просто «пара пар ключ-значение» без определенной структуры;структура все для этого типа.Таким образом, быстрое приведение из набора пар «ключ-значение» (контент без структуры) прямо в словарь (с очень конкретным структурированием) на самом деле невозможно - не то, что структурная структура типа действительно определяет, возможно ли приведение вC # в любом случае (вы должны соблюдать только наследование и несколько встроенных и, возможно, пользовательских преобразований типов).

Подумайте об этом так: словарь является контейнером,не содержание, верно?Поэтому, если у меня есть банка с разными типами печенья, и я хочу вынуть все шоколадные печенья, я могу извлечь их, положить их в небольшую стопку и затем сказать: «Теперь это банка шоколадачип печенье, верно?Нет, я только взял печенье из ;у меня есть куча, а не банка.Если я хочу банку печенья с шоколадной крошкой, тогда мне придется положить их в одну - и это потребует некоторого ненулевого объема работы.

1 голос
/ 31 декабря 2010

Концепция, которую вы упускаете, заключается в том, что ваш код представляет собой запрос к существующему словарю, результатом которого будет IEnumerable<KeyValuePair<K,V>>. Исходный код ожидает, что кто-то определил преобразование для IEnumerable<KeyValuePair<K,V>> в Dictionary<K,V>. По сути, они дали вам возможность самостоятельно определять любое преобразование, поскольку у вас есть метод расширения ToDictionary, который позволяет вам определить ключ, значение и т. Д.

0 голосов
/ 31 декабря 2010

«реальный» результат запроса linq не является словарем, поэтому вы не можете его естественным образом привести.Результатом является IQueryable, поэтому вы должны явно преобразовать его.

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