C# 按属性对对象列表进行分组,拆分为多个列表。
当前结构(不能因系统要求而更改) 示例语句列表C# 按属性对对象列表进行分组,拆分为多个列表。,c#,list,data-structures,struct,C#,List,Data Structures,Struct,当前结构(不能因系统要求而更改) 示例语句列表 section category statement 1 a apple 1 a banana 1 b potato 2 c car 2 c bus 2 d plane
section category statement
1 a apple
1 a banana
1 b potato
2 c car
2 c bus
2 d plane
问题
我从一个列表开始
,需要根据小节将其拆分,然后将其分类为以下(或类似)结构
struct SectionCollection
{
string sectionName {get{return categories[0].section;}}
List<CategoryCollection> categories;
}
struct CategoryCollection
{
string categoryName {get{return statements[0].category;}}
List<Statement> statements;
}
您可以创建一个新的
SectionCollection
对象,其中包含:
SectionCollection thisSection = new SectionCollection();
但是您从不使用new
初始化值thisSection.categories
——无论是在构造函数中还是在外部
因此,当您尝试在内部循环中访问
thisSection.categories.Add
时,会生成一个异常。出现空引用错误的原因是您没有初始化SectionCollection
中的categories
列表
更改:
SectionCollection thisSection = new SectionCollection();
致:
SectionCollection thisSection=新的SectionCollection()
{
类别=新列表()
};
将修复错误。您也没有在任何地方捕获结果,如果您将代码更新到以下位置,它应该可以工作:
var sections = statements.GroupBy(x => x.Section).Select(y => y.ToList()).ToList();
var result = new List<SectionCollection>();
foreach (var section in sections)
{
SectionCollection thisSection = new SectionCollection() { Categories = new List<CategoryCollection>() };
var categories = section.GroupBy(x => x.Category).Select(y => y.ToList()).ToList();
foreach (var category in categories)
{
thisSection.Categories.Add(new CategoryCollection { Statements = category });
}
result.Add(thisSection);
}
var sections=statements.GroupBy(x=>x.Section)。选择(y=>y.ToList()).ToList();
var result=新列表();
foreach(节中的var节)
{
SectionCollection thisSection=new SectionCollection(){Categories=new List()};
var categories=section.GroupBy(x=>x.Category)。选择(y=>y.ToList()).ToList();
foreach(类别中的var类别)
{
添加(新类别集合{Statements=category});
}
结果。添加(本节);
}
但是,为类提供适当的构造函数和属性,并将一些逻辑移到其中,可能会更干净一些:
internal class Program
{
static void Main(string[] args)
{
var statements = new List<Statement>()
{
new Statement(1, "a", "apple"),
new Statement(1, "a", "banana"),
new Statement(1, "b", "potato"),
new Statement(2, "c", "car"),
new Statement(2, "c", "bus"),
new Statement(2, "d", "plane")
};
var sectionCollections = statements
.GroupBy(s => s.Section)
.Select(group => new SectionCollection(group.Key, statements))
.ToList();
}
public class Statement
{
public Statement(int section, string category, string statementName)
{
Section = section;
Category = category;
StatementName = statementName;
}
public int Section { get; }
public string Category { get; }
public string StatementName { get; }
}
public class SectionCollection
{
public SectionCollection(int sectionName, List<Statement> statements)
{
SectionName = sectionName;
Categories = statements
.Where(s => s.Section == sectionName)
.GroupBy(s => s.Category)
.Select(group => new CategoryCollection(group.Key, group.ToList()))
.ToList();
}
public int SectionName { get; }
public List<CategoryCollection> Categories { get; }
}
public class CategoryCollection
{
public CategoryCollection(string categoryName, List<Statement> statements)
{
CategoryName = categoryName;
Statements = statements;
}
public string CategoryName { get; }
public List<Statement> Statements { get; }
}
}
内部类程序
{
静态void Main(字符串[]参数)
{
var语句=新列表()
{
新声明(1,“a”,“苹果”),
新的声明(1,“a”、“香蕉”),
新的声明(1,“b”,“土豆”),
新声明(2,“c”、“car”),
新声明(2,“c”,“总线”),
新的声明(2,“d”,“平面”)
};
var sectionCollections=语句
.GroupBy(s=>s.Section)
.Select(group=>newsectioncollection(group.Key,statements))
.ToList();
}
公开课声明
{
公共语句(int段、字符串类别、字符串语句名称)
{
截面=截面;
类别=类别;
StatementName=StatementName;
}
公共int段{get;}
公共字符串类别{get;}
公共字符串语句名称{get;}
}
公共类集合
{
公共分区集合(int sectionName,List语句)
{
SectionName=SectionName;
类别=声明
.其中(s=>s.Section==sectionName)
.GroupBy(s=>s.Category)
.Select(group=>newcategorycollection(group.Key,group.ToList())
.ToList();
}
public int SectionName{get;}
公共列表类别{get;}
}
公共类类别集合
{
公共CategoryCollection(字符串categoryName,列表语句)
{
CategoryName=CategoryName;
声明=声明;
}
公共字符串CategoryName{get;}
公共列表语句{get;}
}
}
您将得到以下结构:
我看不出
这个部分在哪里。类别是用new
@MFisherKDX初始化的,这可能就是问题所在。。我现在正在研究这个问题,但我觉得我已经尝试过了,只是(愚蠢地)把它从我提供的示例中排除了。我正在进一步研究这个问题,但我不确定这是否是问题所在。(我已经初始化了所有的列表,但仍然面临着上面提供的空引用)好的@Bejasc,继续编辑你的帖子,我会删除我的答案非常感谢@RagtimeWilly,正如我在之前的一篇评论/回复中所说,我已经尝试过初始化构造函数,但在某个时候仍然面临空引用。最终,您在示例中设置LINQ表达式的方式为我指明了解决方案!我发誓,每次和Linq在一起我都会学到新东西!没问题,很高兴你把它整理好了。
SectionCollection thisSection = new SectionCollection()
{
Categories = new List<CategoryCollection>()
};
var sections = statements.GroupBy(x => x.Section).Select(y => y.ToList()).ToList();
var result = new List<SectionCollection>();
foreach (var section in sections)
{
SectionCollection thisSection = new SectionCollection() { Categories = new List<CategoryCollection>() };
var categories = section.GroupBy(x => x.Category).Select(y => y.ToList()).ToList();
foreach (var category in categories)
{
thisSection.Categories.Add(new CategoryCollection { Statements = category });
}
result.Add(thisSection);
}
internal class Program
{
static void Main(string[] args)
{
var statements = new List<Statement>()
{
new Statement(1, "a", "apple"),
new Statement(1, "a", "banana"),
new Statement(1, "b", "potato"),
new Statement(2, "c", "car"),
new Statement(2, "c", "bus"),
new Statement(2, "d", "plane")
};
var sectionCollections = statements
.GroupBy(s => s.Section)
.Select(group => new SectionCollection(group.Key, statements))
.ToList();
}
public class Statement
{
public Statement(int section, string category, string statementName)
{
Section = section;
Category = category;
StatementName = statementName;
}
public int Section { get; }
public string Category { get; }
public string StatementName { get; }
}
public class SectionCollection
{
public SectionCollection(int sectionName, List<Statement> statements)
{
SectionName = sectionName;
Categories = statements
.Where(s => s.Section == sectionName)
.GroupBy(s => s.Category)
.Select(group => new CategoryCollection(group.Key, group.ToList()))
.ToList();
}
public int SectionName { get; }
public List<CategoryCollection> Categories { get; }
}
public class CategoryCollection
{
public CategoryCollection(string categoryName, List<Statement> statements)
{
CategoryName = categoryName;
Statements = statements;
}
public string CategoryName { get; }
public List<Statement> Statements { get; }
}
}