Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于2个唯一ID合并c#中n个列表_C#_Algorithm_Linq_List - Fatal编程技术网

基于2个唯一ID合并c#中n个列表

基于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 ({

我需要一个关于如何根据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 ({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代码?当你让我们的生活更轻松时,你会得到最好的答案。你试图建立的是一个数据透视表。每行表示一个不同的密钥对,显示第一列中的密钥。每个列表在其余列中表示。