迭代集合时创建嵌套对象
问题描述:
迭代时迭代集合并创建嵌套对象是否可能?我有以下的平面列表:迭代集合时创建嵌套对象
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 ]
}
答
好了,这是做
编辑的一种方式:一旦你理解我的代码的工作原理,你可以凝聚一切成单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;
,那么你会重复上剩余的线,并根据需要创建新实例。由于您正在构建分层结构,因此如果创建了新实体,则其所有子实体也会自动变为新实体。因此,需要isNewMachine
和isNewModule
。
恕我直言,在这一点上的代码变得不言自明。
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>()
什么结构是您使用来保持平清单? –