基于2个唯一ID合并c#中n个列表
我需要一个关于如何根据2个键id值合并可能超过2个列表的建议。 我有一个MyType列表,其中MyType包含id1、id2和值字段。我会得到这些列表的一个随机数(比如说n个),我希望合并它们并形成一个新的列表。新列表应该是这样的 Id1、id2、值[n]的列表。。。如果id1、id2在其余列表中匹配,则应将其添加到值[],否则将添加空值 例如:基于2个唯一ID合并c#中n个列表,c#,algorithm,linq,list,C#,Algorithm,Linq,List,我需要一个关于如何根据2个键id值合并可能超过2个列表的建议。 我有一个MyType列表,其中MyType包含id1、id2和值字段。我会得到这些列表的一个随机数(比如说n个),我希望合并它们并形成一个新的列表。新列表应该是这样的 Id1、id2、值[n]的列表。。。如果id1、id2在其余列表中匹配,则应将其添加到值[],否则将添加空值 例如: List1 :- new list ({id1,id2,”Val1”},{id3,id4,”Val2”}); List2 :- new list ({
List1 :- new list ({id1,id2,”Val1”},{id3,id4,”Val2”});
List2 :- new list ({id1,id2,”Val3”},{id3,id5,”Val4”}, {id6,id4,”Val5”});
List3 :- new list ({id1,id2,”Val4”},{id3,id4,”Val7”},{id6,id7,”Val8”},{id6,id4,”Val9”});
合并后,新列表应包含:
MergeIist:- {id1,id2,[“Val1”,”val3”,”val4”]},{id3,id4,[“Val2”,NULL,”Val7”]},{id3,id5,[NULL,”Val4”,NULL]},
{ id6,id4,[NULL,”Val5”,”Val9”] },{ id6,id7,[NULL,NULL,”Val8”] }
我心里有一个算法,但这是非常昂贵的,比如给列表中的每个条目添加一个标志,比如“已处理”,然后比较列表中的所有条目并合并。有没有一种聪明的方法来处理这个问题?我认为您需要创建一个字典来存储出现的id1值列表,然后为每个值创建一个字典来存储出现的id2值列表,最后是该组合出现的字符串列表。所以像这样的事情
Dictionary<int, Dictionary<int, List<string>>> x;
字典x;
现在,从每个源列表中枚举每个三元组,然后对第一个id执行查找,对第二个id执行查找,最后对字符串列表执行追加。完成后,您可以通过处理上述数据结构的三个级别来生成新列表。以下是LINQ解决方案;我说不出它有多高效
var list1 = new [] { new MyType {Id1="1", Id2="2", Value="Val1" }, new MyType {Id1="3", Id2="4", Value="Val2" }};
var list2 = new [] { new MyType {Id1="1", Id2="2", Value="Val3" }, new MyType {Id1="3", Id2="5", Value="Val4" }, new MyType {Id1="6", Id2="4", Value="Val5" }};
var list3 = new [] { new MyType {Id1="1", Id2="2", Value="Val4" }, new MyType {Id1="3", Id2="4", Value="Val7" }, new MyType {Id1="6", Id2="7", Value="Val8" }, new MyType {Id1="6", Id2="4", Value="Val9" }};
var lists = new [] {list1, list2, list3};
var ids = lists.SelectMany(t => t).
Select(t => new { Id1=t.Id1, Id2=t.Id2 }).
Distinct().ToList();
var output = ids.Select(id => new MyTypeConsolidated {
Id1=id.Id1, Id2=id.Id2, Value =
lists.Select(ls => {
var match = ls.FirstOrDefault(t => t.Id1 == id.Id1 && t.Id2 == id.Id2);
return match == null ? null : match.Value;
}).ToArray()
});
使用的类别:
class MyType {
public string Id1;
public string Id2;
public string Value;
}
class MyTypeConsolidated {
public string Id1;
public string Id2;
public string[] Value;
}
输出:
1, 2, [Val1,Val3,Val4]
3, 4, [Val2,NULL,Val7]
3, 5, [NULL,Val4,NULL]
6, 4, [NULL,Val5,Val9]
6, 7, [NULL,NULL,Val8]
这是一个可行的方法。这里有一个替代方法-它与Blorgbeard的答案非常相似,但我怀疑这在处理较大的列表时会更有效 我也是这样开始的:
var list1 = new [] { new { X = "1", Y = "2", Value = "Val1" }, new { X = "3", Y = "4", Value = "Val2" }};
var list2 = new [] { new { X = "1", Y = "2", Value = "Val3" }, new { X = "3", Y = "5", Value = "Val4" }, new { X = "6", Y = "4", Value = "Val5" }};
var list3 = new [] { new { X = "1", Y = "2", Value = "Val4" }, new { X = "3", Y = "4", Value = "Val7" }, new { X = "6", Y = "7", Value = "Val8" }, new { X = "6", Y = "4", Value = "Val9" }};
var lists = new [] { list1, list2, list3 };
var ids =
lists
.SelectMany(z => z)
.Select(z => new { z.X, z.Y })
.Distinct()
.ToArray();
然后我创建了一个查找字典:
var lookups =
lists
.Select((z, n) => new
{
Index = n,
Lookup = z.ToLookup(w => new { w.X, w.Y }, w => w.Value),
})
.ToDictionary(z => z.Index, z => z.Lookup);
最后,我生成输出:
var output =
from id in ids
select new
{
id.X,
id.Y,
Values =
lists
.SelectMany((_, n) => lookups[n][new { id.X, id.Y }].DefaultIfEmpty(null))
.ToArray(),
};
输出符合要求。您是否有可能为示例数据和所需输出提供可编译的c代码?当你让我们的生活更轻松时,你会得到最好的答案。你试图建立的是一个数据透视表。每行表示一个不同的密钥对,显示第一列中的密钥。每个列表在其余列中表示。