我有两个var HeaderView = TemplateView.extend({
tagName: 'header',
templateName: '#header-template',
events: {
'click a.logout': 'logout'
},
getContext: function () {
return {authenticated: app.session.authenticated()};
},
logout: function (event) {
event.preventDefault();
console.log('clicked');
app.session.delete();
window.location = '/';
}
});
List<Dictionary<string, string>>
我想合并两个列表,并按键对值进行分组。结果是List<Dictionary<string, string>> ListdicA = new List<Dictionary<string, string>>();
Dictionary<string, string> dic1 = new Dictionary<string, string>();
dic1.Add("Type1", "1");
dic1.Add("Type2", "A");
dic1.Add("Type3", "X");
Dictionary<string, string> dic2 = new Dictionary<string, string>();
dic2.Add("Type1", "2");
dic2.Add("Type2", "B");
dic2.Add("Type3", "Y");
ListdicA.Add(dic1);
ListdicA.Add(dic2);
List<Dictionary<string, string>> ListdicB = new List<Dictionary<string, string>>();
Dictionary<string, string> dic3 = new Dictionary<string, string>();
dic3.Add("Type1", "1");
dic3.Add("Type2", "C");
dic3.Add("Type3", "X");
Dictionary<string, string> dic4 = new Dictionary<string, string>();
dic4.Add("Type1", "2");
dic4.Add("Type2", "D");
dic4.Add("Type3", "Z");
ListdicB.Add(dic3);
ListdicB.Add(dic4);
。首先,我想合并两个列表:
List<Dictionary<string, List<string>>>
我希望用键对它进行分组,结果如下:
Type1 1
Type2 A
Type3 X
Type1 2
Type2 B
Type3 Y
Type1 1
Type2 C
Type3 X
Type1 2
Type2 D
Type3 Z
答案 0 :(得分:1)
基于问题更新:
这非常复杂(至少对我而言)。我展示了这些步骤,并且我还将每个LINQ放在括号中,从而完成了这项工作。
1)你必须加入两个名单。 (ListdicA.Concat(ListdicB)
)
2)按每个词典Type1
键的值对所有词典进行分组。(GroupBy(x => x["Type1"])
)
3)将所有项目IGrouping<string,Dictionary<string,string>>
展开到KeyValuePair<string,string>
(SelectMany(y => y)
)
4)再次按Key键组键值,以便将相同键的值连接在一起(GroupBy(y => y.Key)
)
5)将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()
放在那里,则会删除重复项
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
,那么您需要自定义区别。你需要这门课。 (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
如果您有任何问题,请随时提出。
虽然这完全融化了我的想法,但这是一个很好的做法!。
答案 1 :(得分:0)
如果你这样做
ListdicA.Zip(ListdicB, (a,b) => a.Concat(b)
.GroupBy(x => x.Key)
.Select (g => new
{
g.Key,
Values = g.SelectMany(d => d.Value).Distinct()
} ))
你得到这个结果:
Type 1 1
Type 2 A
C
Type 3 X
Type 1 2
Type 2 B
D
Type 3 Y
Z
我不确定您的X X
结果是故意还是错字。如果它有意,我应该添加一些逻辑。