迭代集合时创建嵌套对象

问题描述:

迭代时迭代集合并创建嵌套对象是否可能?我有以下的平面列表:迭代集合时创建嵌套对象

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; } 
} 

所以平面文件将创建一个工具对象与工厂的集合(即“FACTA”和“factb “)。 'facta'工厂将包含一系列机器(即'123'和789')。 'fact'中的'123'机器将包含一系列模块(即'abc','def','ghi'),等等......

JSON表示我在想什么:

{ 
 
\t "factory": [ 
 
\t \t { \t \t \t 
 
\t \t \t "name": "facta", 
 
\t \t \t "machine": [ 
 
\t \t \t \t { \t \t 
 
\t \t \t \t \t "name": "123", 
 
\t \t \t \t \t "modules": [ 
 
\t \t \t \t \t \t { "name" : "abc"}, 
 
\t \t \t \t \t \t { "name" : "def"}, 
 
\t \t \t \t \t \t { "name" : "ghi"} 
 
\t \t \t \t \t ] 
 
\t \t \t \t }, 
 
\t \t \t \t { \t \t \t \t \t 
 
\t \t \t \t \t "name": "789", 
 
\t \t \t \t \t "modules": [ 
 
\t \t \t \t \t \t { "name" : "jkl"}, 
 
\t \t \t \t \t \t { "name" : "mno"} 
 
\t \t \t \t \t ] 
 
\t \t \t \t } 
 
\t \t \t ] 
 
\t \t }, 
 
\t \t { \t \t \t 
 
\t \t \t "name": "factb", 
 
\t \t \t "machine": [ 
 
\t \t \t \t { \t \t \t \t \t 
 
\t \t \t \t \t "name": "456", 
 
\t \t \t \t \t "modules": [ 
 
\t \t \t \t \t \t { "name" : "abc"}, 
 
\t \t \t \t \t \t { "name" : "def"}, 
 
\t \t \t \t \t \t { "name" : "ghi"}, 
 
\t \t \t \t \t \t { "name" : "jkl"}, 
 
\t \t \t \t \t \t { "name" : "mno"} 
 
\t \t \t \t \t ] 
 
\t \t \t \t } 
 
\t \t \t ] 
 
\t \t } 
 
\t ] 
 
}

+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; 
    } 
} 

开箱,我什么都不知道,可以使这一点。 当然,这是可能的。

你可以为listItems中

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}); 

假设你的单位名单是一个数组的一个数组里面:

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

我也假设你有一个模块类呢?

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>()