Я получаю оставшиеся служебные данные, которые я преобразовал в словарь строк, список строк.
Теперь мне нужна возможность получить легкий доступ к значениям из списка строк в качестве ключей в новом словаре, а ключи из исходного словаря должны быть перенесены в список строк
пример:
входной словарь:
keys: Key1: Values: va11 val2 val3 Key2: Values: val2 val4 val5 Key3: Values: val1 val5 val6
ожидаемый выходной словарь:
keys: val1: Values: key1 key3 val2: Values: Key1 val3: Values: key1 val4: Values: key2 val5: Values: Key2 Key3 val6: Values: key3
До сих пор я использовал цикл foreach во втором цикле foreach для чтения существующего словаря и заполнения нового.
_M210_simplified — входной словарь (строки, списка (строки))
Код для заполнения нового диска:
Dim oonew As New Dictionary(Of String, List(Of String))
For Each oo In _M210_simplified
Dim olist = oo.Value
For Each osub In olist
If oonew.ContainsKey(osub) Then
oonew.Item(osub).Add(oo.Key)
Else
Dim oln As New List(Of String)
oln.Add(oo.Key)
oonew.Add(osub, oln)
End If
Next
Next
Но в случае огромных данных (в словаре будет более 100 000 записей), я думаю, что производительность, вероятно, будет намного лучше при использовании linq с лямбда-функциями.
мне нужен правильный синтаксис LINQ в VB.Net или C# для этого перевода
Спасибо
спасибо @NineBerry за редактирование сообщения, теперь оно намного лучше читается!
Код в комментариях не существует. Ваш код принадлежит вашему вопросу, где его можно увидеть. У вас есть возможность редактировать свой пост, используя ссылку под тегами.
LINQ не является средством повышения производительности. Вообще говоря, код LINQ будет работать хуже, чем лучшая альтернатива. LINQ — это способ сделать ваш код более кратким. Снижение производительности, как правило, будет незначительным, но оно будет.
Разместите код в своем вопросе. Мой совет: если вы обнаружите, что создаете коллекции коллекций, создайте класс, который представляет данные и поведение.
var index = dict.SelectMany(i => i.Value.Select(v => new {i.Key, v})).ToLookup(i => i.v, i => i.Key)
?
Вы можете (слегка) оптимизировать свой код, заменив внутренний For Each
циклом For
, а затем использовать TryGetValue
вместо ContainsKey
, чтобы не выполнять два поиска.
Не уверен, почему люди утверждают, что этот вопрос не ясен.
Это правда, что выполнение этого в LINQ может быть не более производительным, но компилятор может оптимизировать длинные запросы LINQ, когда они перечисляются.
С другой стороны, поиск ключей по словарю, как и в вашем цикле, выполняется очень быстро, поэтому ваш цикл может быть еще быстрее. Единственный способ убедиться в этом — проверить.
Это один из способов сделать это в одном запросе LINQ, по существу сводя ваш первый словарь к {diction1.Value, Dictionary1.Key}, а затем группируя их по Dictionary1.Value, так что вы получаете все ключи Dictionary1 для каждого словаря1. ценить:
var dictionary1 = new Dictionary<string, List<string>>();
Dictionary<string, List<string>> dictionary2;
dictionary2 = dictionary1
//flatten:
.SelectMany(dict1KeyValue =>
dict1KeyValue.Value.Select(dict1Value => new { dict1Value, dict1Key = dict1KeyValue.Key}))
.GroupBy(flattened => flattened.dict1Value) // Group up by dictionary1's values
.ToDictionary(
dict1ValueGroup => dict1ValueGroup.Key,
dict1ValueGroup => dict1ValueGroup.Select(vg => vg.dict1Key).ToList());
Компилятор не оптимизирует длинные цепочки запросов LINQ. Существует некоторая оптимизация преобразования запросов LINQ в объекты, представляющие запрос, но она довольно минимальна. Существует множество оптимизаций компилятора для циклов for
и foreach
.
@zola25. Спасибо за ответ, предоставленные коды дают вполне ожидаемый результат.
@ Все о производительности, я сравнивал ее несколько раз, и да, вы правы, производительность на самом деле не улучшилась с помощью lync. В большинстве случаев двойник для каждого цикла имел лучшую производительность...
Было бы полезно опубликовать свой код, например, цикл foreach.