迭代集合时创建嵌套对象

时间:2016-11-16 08:43:25

标签: c# loops collections

迭代时是否可以迭代集合并创建嵌套对象?我有以下单位:

TOOLID    FACTORY     MACHINE     MODULE
1         facta       123         abc
2         facta       123         def
3         facta       123         ghi
4         facta       789         jkl
5         facta       789         mno
6         factb       456         abc
7         factb       456         def
8         factb       456         ghi
9         factb       456         jkl
10        factb       456         mno

我定义了以下类:

public class Tool
{
    public List<Factory> Factories { get; set; }    
}
public class Factory
{    
    public string Name { get; set; }
    public List<Machine> Machines { get; set; }
}
public class Machine
{    
    public string Name { get; set; }
    public List<Module> Modules { get; set; }
}

因此,平面文件将创建一个Tool对象,其中包含一系列工厂(即&#39; facta&#39;&#39; factb&#39;)。 &#39; FACTA&#39;工厂将包含一系列机器(即&#39; 123&#39;和789&#39;)。 &#39; 123&#39;机器内部&#39; facta&#39;将包含一系列模块(即&#39; abc&#39;,&#39; def&#39;,&#39; ghi&#39;),等等...

JSON代表我所想的:

&#13;
&#13;
{
	"factory": [
		{			
			"name": "facta",
			"machine": [
				{		
					"name": "123",
					"modules": [
						{ "name" : "abc"},
						{ "name" : "def"},
						{ "name" : "ghi"}
					]
				},
				{					
					"name": "789",
					"modules": [
						{ "name" : "jkl"},
						{ "name" : "mno"}
					]
				}
			]
		},
		{			
			"name": "factb",
			"machine": [
				{					
					"name": "456",
					"modules": [
						{ "name" : "abc"},
						{ "name" : "def"},
						{ "name" : "ghi"},
						{ "name" : "jkl"},
						{ "name" : "mno"}
					]
				}
			]
		}
	]
}
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

假设您的平面列表是数组中的数组:

string[][] flatList = new string[10][4];

我也假设你有一个Module类?

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

您首先要初始化并填充第一行数据中存在的四个独立实体:

Tool tool = new Tool(){Factories = new List<Factories>()};
Factory factory = new Factory(){Name = flatList[0][1], Machines = new List< Machine>()};
tool.Factories.Add(factory);
Machine machine = new Machine(){Name = flatList[0][2], Modules = new List<Module>()};
factory.Machines.Add(machine);
Module module = new Module(){Name = flatList[0][3]};
machine.Modules.Add(module);
bool isNewMachine = false;
bool isNewModule = false;

然后,您将迭代剩余的行并根据需要创建新实例。因为您正在构建分层结构,所以如果创建了新实体,则其所有子实体也将自动成为新实体。因此,需要isNewMachineisNewModule

恕我直言,此时代码变得不言自明了。

for(int i = 1; i < flatList.Length; i++)
{
    if(factory.Name != flatList[i][1]) //factory is different from previous
    {
        factory = new Factory(){Name = flatList[i][1], Machines = new List< Machine>()};
        tool.Factories.Add(factory);
        isNewMachine = true;
        isNewModule = true;
    }
    if(isNewMachine || machine.Name != flatList[i][2]) //machine is different from previous
    {
        machine = new Machine(){Name = flatList[][2], Modules = new List<Module>()};
        factory.Machines.Add(machine);
        isNewMachine = false;
        isNewModule = true;
    }
    if(isNewModule || module.Name != flatList[i][3]) //module is different than previous
    {
        module = new Module(){Name = flatList[0][3]};
        machine.Modules.Add(module);
        isNewModule = false;
    }
}

此外,根据您使用的.NET框架版本,您可以通过自动实例化类的List属性来减少代码量。例如,您的Tool实体将如下所示:

public class Tool
{
    public List<Factory> Factories { get; set; } = new List<Factory>();
}

然后,您可以删除当前实例化每个实例列表所需的所有代码行:

 ... ], Modules = new List<Module>()

答案 1 :(得分:0)

开箱即用,我不知道能做到这一点的任何事情。 当然,这是可能的。

您可以为列表项

创建一个类
public class FlatItem
{
    public int ToolId {get;set;}
    public string Factory {get;set;}
    public int Machine {get;set;}
    public string Module {get;set;}
}

List<FlatItem> flatitemlist = ... // get your flatlist into this list

然后,我建议您使用System.Linq GroupBy扩展名(或linq查询group by),如下所示:

var result = flatitemlist
                .GroupBy(g => g.Factory)
                .Select(t => t
                    .GroupBy(g => g.Machine)
                    .Select(x => x
                        .GroupBy(y => y.Module))).ToList();

所以你得到了结构,你可以遍历这些项目。

也许,也看看这个:

var result = flatitemlist.GroupBy(x => new {x.Factory, x.Machine, x.Module});

答案 2 :(得分:0)

嗯,这是一种做法

编辑:一旦你理解了我的代码的工作原理,你就可以将所有内容压缩成一个Linq行:

to = new Tool();
input.GroupBy(a => a[1]).ToList().ForEach(a =>
    { fa = new Factory($"{a.Key}"); a.GroupBy(b => b[2]).ToList().ForEach(b =>
        { ma = new Machine($"{b.Key}"); b.GroupBy(c => c[3]).ToList().ForEach(c =>
            { mo = new Module($"{c.Key}"); ma.Modules.Add(mo); }); fa.Machines.Add(ma); }); to.Factories.Add(fa); });

原始代码:

static class Program
{
    static void Main(string[] args)
    {
        Tool to;
        Factory fa;
        Machine ma;
        Module mo;
        List<ArrayList> input = new List<ArrayList>();

        input.Add(new ArrayList() { 1, "facta", 123, "abc" });
        input.Add(new ArrayList() { 2, "facta", 123, "def" });
        input.Add(new ArrayList() { 3, "facta", 123, "ghi" });
        input.Add(new ArrayList() { 4, "facta", 789, "jkl" });
        input.Add(new ArrayList() { 5, "facta", 789, "mno" });
        input.Add(new ArrayList() { 6, "factb", 456, "abc" });
        input.Add(new ArrayList() { 7, "factb", 456, "def" });
        input.Add(new ArrayList() { 8, "factb", 456, "ghi" });
        input.Add(new ArrayList() { 9, "factb", 456, "jkl" });
        input.Add(new ArrayList() { 10, "factb", 456, "mno" });

        //[0] = ToolId / [1] = FactoryName / [2] = MachineName / [3] = ModuleName

        var factories = input.GroupBy(a => a[1]);
        to = new Tool();

        foreach (var factory in factories)
        {
            fa = new Factory($"{factory.Key}");
            var machines = factory.GroupBy(a => a[2]);
            foreach (var machine in machines)
            {
                ma = new Machine($"{machine.Key}");
                var modules = machine.GroupBy(a => a[3]);
                foreach (var module in modules)
                {
                    mo = new Module($"{module.Key}");
                    ma.Modules.Add(mo);
                }
                fa.Machines.Add(ma);
            }
            to.Factories.Add(fa);
        }
    }
}
public class Tool
{
    public List<Factory> Factories { get; set; }
    public Tool()
    {
        Factories = new List<Factory>();
    }
}
public class Factory
{
    public string Name { get; set; }
    public List<Machine> Machines { get; set; }
    public Factory(string name)
    {
        Name = name;
        Machines = new List<Machine>();
    }
}
public class Machine
{
    public string Name { get; set; }
    public List<Module> Modules { get; set; }
    public Machine(string name)
    {
        Name = name;
        Modules = new List<Module>();
    }
}
public class Module
{
    public string Name { get; set; }
    public Module(string name)
    {
        Name = name;
    }
}