2014-01-16 3 views
2

В настоящее время у меня есть Dictionary<Key, IEnumerable<Value>>, и я хочу его развернуть, поэтому он станет Dictionary<Key, Value>.Расширение IDictionary <Key, IEnumerable <Value>>

Делать это с помощью простого цикла Еогеасп легко, но и грязный:

var result = new List<KeyValuePair<Key, Value>>(); 
foreach(var kvp in dict) 
{ 
    foreach(var v in kvp.Value) 
    { 
     result.Add(new KeyValuePair<Key, Value>(kvp.Key, v)); 
    } 
} 

Теперь я хотел бы, чтобы преобразовать это в одном запросе LINQ, и предпочтительно с использованием синтаксиса лямбда. (В настоящее время не используется синтаксис выражения везде в проекте, и не чувствую, начиная с сегодняшнего дня)

+3

Это должно взорвать вас, поскольку словари поддерживают только одно значение за ключ. Вам нужен MultiDictionary, и нет такой вещи, встроенной в библиотеки базового класса. – Trillian

+0

Прежде всего, вы не протестировали цикл, который вы пытаетесь преобразовать в запрос Single LINQ. Это вызовет исключение «Key Already Exists» при первом значении IEnumerable с более чем одним членом. –

+0

@Trillian @BolucPapuccuoglu Хорошая точка, я должен, вероятно, изменить ее на '' IEnumerable > '' – Kippie

ответ

3

Вы не можете добавить один и тот же ключ дважды, но это произойдет в вашем вложенном цикле.

Если вместо этого вы хотите, чтобы сгладить его к IEnumerable<KeyValuePair<Key, Value>>, как прокомментировал вы можете использовать SelectMany:

var dict = new Dictionary<string, IEnumerable<string>>(); 
IEnumerable<KeyValuePair<string, string>> flattenedDict = dict 
    .SelectMany(kv => 
     kv.Value.Select(v => new KeyValuePair<string, string>(kv.Key, v))); 
+0

Отлично, это делает работу! – Kippie

1

Как об этом с помощью LINQ инлайн:

var results = (from kvp in dict 
       from v in kvp.Value 
       select new KeyValuePair<AddressType, ContractType>(kvp.Key, v)) 
       .ToList(); 

Не знаю, о синтаксисе лямбда, хотя ,

+0

Ну, это работает, хотя я бы ** действительно ** хотел это быть лямбдой. – Kippie

0

Вы могли бы, возможно, использовать Lookup<T> как он поддерживает несколько ключей в значение,

var dict = new Dictionary<string, IEnumerable<string>>(); 
var lookUp = dictionary 
    .SelectMany(pair => pair.Value 
     .Select(value => new { Key = pair.Key, Value = value })) 
    .ToLookup(pair => pair.Key, pair => pair.Value); 
Смежные вопросы