Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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
C# C使用LINQ将两个具有嵌套列表的列表合并为一个_C#_Linq - Fatal编程技术网

C# C使用LINQ将两个具有嵌套列表的列表合并为一个

C# C使用LINQ将两个具有嵌套列表的列表合并为一个,c#,linq,C#,Linq,我在c中有两个如下结构的列表。中的每个名称都是一个列表。我想把这两个列表合并成一个列表。以下伪代码显示了两个这样的列表以及结果的外观: <Servers> <Servers> +... +... +-- Server A,1 +-- Server A,1 | +...

我在c中有两个如下结构的列表。中的每个名称都是一个列表。我想把这两个列表合并成一个列表。以下伪代码显示了两个这样的列表以及结果的外观:

<Servers>                           <Servers>
+...                                +...
+-- Server A,1                      +-- Server A,1
|       +...                        |       +...    
|       +--<Maps>                   |       +--<Maps>
|           +--Map x                |           +--Map x
|               +...                |               +...    
|               +--<Times>          |               +--<Times>
|                   +--Time i       |                   +--Time l
|                   +--Time j       |               +--<Jumps>
|               +--<Jumps>          |                   +--Jump t
|                   +--Jump s       |                   +--Jump u
|           +--Map y                |           +--Map z
|               +...                |               +...
|               +--<Times>          |               +--<Jumps>  
|                   +-- Time k      |                   +--Jump v
+-- Server B,1                      +-- Server B,2

您可能一直在寻找.Union,但它不处理嵌套列表,所以我认为它不是您真正需要的。我建立了一个完整的示例,虽然其结构与您的不同,但我认为您可以轻松应用核心linq:

using System;
using System.Collections.Generic;
using System.Linq;

public class Map
{
    public string Name { get; set; }
    public IEnumerable<MapProperty> Properties { get; set; }
}

public class MapProperty
{
    public string Name { get; set; }
}

public class Test
{
    public static IEnumerable<Map> Merge(IEnumerable<Map> a, IEnumerable<Map> b)
    {
        return a.Concat(b)
            .GroupBy(map => map.Name)
            .Select(mg => new Map
            {
                Name = mg.Key,
                Properties = mg.SelectMany(v => v.Properties)
                    .GroupBy(p => p.Name)
                    .Select(pg => new MapProperty { Name = pg.Key })
            });
    }

    public static void Main()
    {
        var mapsA = new[]
        {
            new Map
            {
                Name = "MapA",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Hops" },
                }
            },
            new Map
            {
                Name = "MapB",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Skips" },
                }
            }
        };
        var mapsB = new[]
        {
            new Map
            {
                Name = "MapA",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Times" },
                }
            },
            new Map
            {
                Name = "MapC",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Skips" },
                }
            }
        };

        var mapsC = Merge(mapsA, mapsB);

        foreach (var map in mapsC)
        {
            Console.WriteLine($"{map.Name}");
            foreach (var prop in map.Properties)
            {
                Console.WriteLine($"\t{prop.Name}");
            }
        }
    }
}
合并是重要的一点。它首先将a和b全部放在一个列表中,然后GroupBy name形成具有相同名称的地图组。Select将获取每个组,并使用该组中所有映射的内容创建一个新映射。这是“合并!”!。然后,我对新合并的地图的内容做了同样的操作,将MapProperty分组并合并它们


在您的特定情况下,您将需要更多的工作和级别来合并所有内容。我建议找到一种方法,为树中的每个级别创建一个合并方法,并从每个父级调用下一个级别,这样您就不会得到一个庞大的linq链。

我认为您的想法是正确的。看起来您刚刚给嵌套联接传递了错误的参数!例如,在Maps join中,您试图加入coreServer.Maps和oImportList。。。我怀疑这应该是coreServer.Maps和importServer.Maps。在您的帮助下,我能够让代码正常工作,但后来我发现结果并不是我想要的列表。它只包含两个列表中都存在的元素。啊,对不起。。。我很少使用Join,所以我把它弄混了。我已使用GroupBy取消删除了一个答案,并选择了可能适合您的答案。我以前删除过它,因为我认为我走错了方向。
  foreach (Server importServer in oImportList)
        {
            if (!CoreList.Contains(importServer))
            {
                CoreList.Add(importServer);
                continue;
            }

            Server coreServer = CoreList.FirstOrDefault(o => o.Equals(importServer));
            coreServer.Name = importServer.Name;
            coreServer.KZTimerVersion = importServer.KZTimerVersion;
            foreach(Map importMap in importServer.Maps)
            {
                if (!coreServer.Maps.Contains(importMap))
                {
                    coreServer.Maps.Add(importMap);
                    continue;
                }
                Map coreMap = coreServer.Maps.FirstOrDefault(o => o.Equals(importMap));
                coreMap.Jumps.Concat(importMap.Jumps);
                coreMap.Times.Concat(importMap.Times);
            }
        }
using System;
using System.Collections.Generic;
using System.Linq;

public class Map
{
    public string Name { get; set; }
    public IEnumerable<MapProperty> Properties { get; set; }
}

public class MapProperty
{
    public string Name { get; set; }
}

public class Test
{
    public static IEnumerable<Map> Merge(IEnumerable<Map> a, IEnumerable<Map> b)
    {
        return a.Concat(b)
            .GroupBy(map => map.Name)
            .Select(mg => new Map
            {
                Name = mg.Key,
                Properties = mg.SelectMany(v => v.Properties)
                    .GroupBy(p => p.Name)
                    .Select(pg => new MapProperty { Name = pg.Key })
            });
    }

    public static void Main()
    {
        var mapsA = new[]
        {
            new Map
            {
                Name = "MapA",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Hops" },
                }
            },
            new Map
            {
                Name = "MapB",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Skips" },
                }
            }
        };
        var mapsB = new[]
        {
            new Map
            {
                Name = "MapA",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Times" },
                }
            },
            new Map
            {
                Name = "MapC",
                Properties = new[]
                {
                    new MapProperty { Name = "Jumps" },
                    new MapProperty { Name = "Skips" },
                }
            }
        };

        var mapsC = Merge(mapsA, mapsB);

        foreach (var map in mapsC)
        {
            Console.WriteLine($"{map.Name}");
            foreach (var prop in map.Properties)
            {
                Console.WriteLine($"\t{prop.Name}");
            }
        }
    }
}
MapA
    Jumps
    Hops
    Times
MapB
    Jumps
    Skips
MapC
    Jumps