основе Вопрос обновления:
Этот очень сложный (по крайней мере, это было для меня). Я показал шаги, а также я помещаю каждый LINQ в круглые скобки, которые выполняют часть этой работы.
1) Вам необходимо присоединиться к двум спискам. (ListdicA.Concat(ListdicB)
)
2) Группа всех словари величина Type1
ключа в каждых словарях. (GroupBy(x => x["Type1"])
)
3) UnWrap всех товаров IGrouping<string,Dictionary<string,string>>
к KeyValuePair<string,string>
(SelectMany(y => y)
)
4) Снова Группа пары значения ключа Клав, так что вы присоединитесь значения одинаковых ключей вместе (GroupBy(y => y.Key)
)
5) UnWrap IGrouping<string,KeyValuePair<string,string>>
в IEnumerable<KeyValuePair<string,List<string>>>
(Select(y => new KeyValuePair<string, List<string>>(y.Key, y.Select(z => z.Value).ToList()))
)
6) Преобразование IEnumerable<IEnumerable<KeyValuePair<string,List<string>>>>
в IEnumerable<Dictionary<string,List<string>>>
(Select(x => x.ToDictionary(y => y.Key, y => y.Value))
)
7) Наконец Преобразовать IEnumerable<Dictionary<string,List<string>>>
в List<Dictionary<string, List<string>>>
(ToList()
)
string groupby = "Type1";
List<Dictionary<string, List<string>>> result =
ListdicA.Concat(ListdicB).GroupBy(x => x[groupby]).Select(x =>
x.SelectMany(y => y) // Put .Distinct() here to remove duplicates.(optional)
.GroupBy(y => y.Key).Select(y => new KeyValuePair<string, List<string>>(y.Key, y.Select(z => z.Value).ToList())))
.Select(x => x.ToDictionary(y => y.Key, y => y.Value)).ToList();
foreach (var d in result)
{
foreach (var k in d)
{
Console.Write(k.Key + " : ");
foreach (var l in k.Value)
{
Console.Write(l + " ");
}
Console.WriteLine();
}
}
Выходы
Type1 1 1
Type2 A C
Type3 X X
Type1 2 2
Type2 B D
Type3 Y Z
Как я отметил в комментарии (внутри кода), если вы удалите этот комментарий и поместите .Distinct()
righ t там будет удалено дубликатов
List<Dictionary<string, List<string>>> result =
ListdicA.Concat(ListdicB).GroupBy(x => x[groupby]).Select(x => x.SelectMany(y => y)
.Distinct().GroupBy(y => y.Key)
.Select(y => new KeyValuePair<string, List<string>>(y.Key, y.Select(z => z.Value).ToList())))
.Select(x => x.ToDictionary(y => y.Key, y => y.Value)).ToList();
будет выводиться.
Type1 1
Type2 A C
Type3 X
Type1 2
Type2 B D
Type3 Y Z
Если вы не хотите потерять X
, то вам нужно пользовательские Distinct. Вам понадобится этот класс. (linq was taken and edited from here)
public static class SomeMoreLinq
{
public static IEnumerable<TSource> DistinctIf<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> keySelector)
{
HashSet<TSource> seenKeys = new HashSet<TSource>();
foreach (TSource element in source)
{
if (seenKeys.Add(element) || !keySelector(element))
{
yield return element;
}
}
}
}
И затем используйте его в своем запросе.
List<Dictionary<string, List<string>>> result =
ListdicA.Concat(ListdicB).GroupBy(x => x[groupby]).Select(x => x.SelectMany(y => y)
.DistinctIf(y => y.Key == groupby).GroupBy(y => y.Key)
.Select(y => new KeyValuePair<string, List<string>>(y.Key, y.Select(z => z.Value).ToList())))
.Select(x => x.ToDictionary(y => y.Key, y => y.Value)).ToList();
будет выводиться.
Type1 1
Type2 A C
Type3 X X
Type1 2
Type2 B D
Type3 Y Z
Если у вас есть вопросы, задайте вопросы.
Хотя это полностью расплавило мой разум, но это была хорошая практика !.
Я не уверен, что понимаю логические условия группировки. Не могли бы вы изменить свой вопрос, чтобы включить подробную информацию о том, как следует выполнять различные группировки? –
Я хочу объединить два списка и сгруппировать их по Type1 @Luc Morin –
Вам нужно присоединиться к ключам двух словарей, используя внешнее соединение, так как вам нужно включить все ключи обоих словарей. См. Следующую веб-страницу: https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng