c# - c# 按顺序对嵌套列表进行分组
问题描述
我在 c# 中生成如下的 yaml:
- type: DEFAULT
primitives:
- sequenceNo: 1
from: Environment
to: uC
event: register
- type: DEFAULT
primitives:
- sequenceNo: 4
from: uP
event: start cells
- type: LOOP
primitives:
- sequenceNo: 5
from: uC
to: uP
event: keepAlive Question
- type: LOOP
primitives:
- sequenceNo: 6
from: uP
to: uC
event: keepAlive Response
- type: DEFAULT
primitives:
- sequenceNo: 10
from: uC
to: uP
event: switch off uP
以下是我的课程:
public class Type
{
public string type { get; set; }
public List<Primitive> primitives { get; set; }
}
public class Primitive
{
[YamlIgnore]
public int sequenceNo { get; set; }
[YamlIgnore]
public int startX { get; set; }
[YamlIgnore]
public int startY { get; set; }
public string from { get; set; }
public string to { get; set; }
[YamlMember(Alias = "event")]
public string events { get; set; }
public string expectedState { get; set; }
}
我想将列表分组如下:
- type: DEFAULT
primitives:
- from: environment
to: uC
event: register
- from: uP
event: start cells
- type: LOOP
primitives:
- from: uC
to: uP
event: keepAlive Question
- from: uP
to: uC
event: keepAlive Response
- type: DEFAULT
primitives:
from: uC
to: uP
event: switch off uP
这意味着,我想根据类型按顺序对它们进行分组。如果我能找到相同的组,例如一个接一个的 DEFAULT,我必须将 2 个顺序 DEFAULT 的原语分组到一个 DEFAULT 中,依此类推。我怎样才能做到这一点。到目前为止,我已经尝试使用如下字典:
var res = types.GroupBy(r => r.type)
.ToDictionary(t => t.Key, t => t.Select(r => r.primitives).ToList());
但我没有按顺序获得列表。
解决方案
每当您有一系列相似的项目,并且您想要创建具有共同点的项目组时,请考虑使用GroupBy的重载之一。
您希望使这些组的Primitives
属性具有相同的值Type
。我的建议是使用具有参数 resultSelector 的 GroupBy 的重载。
(为了防止对类 Type 和属性 Type 的误解,我使用 originalType 来标识你原来的 Types 集合中的一个元素)
首先,我将创建original types
具有相同属性类型值的组。然后,从这个 Group 中的元素序列(它们是原始类型)中,获取它们的基元,并将其展平(SelectMany)。从中选择所需的属性。
// make groups of Types that have same value of property Type:
IEnumerable<Type> originalTypes = ...
var result = originalTypes.GroupBy(originalType => originalType.Type,
// parameter resultSelector: from every Type, and all original types that have this
// value of property Type, make one new:
(type, originalTypesThatHaveThisValueForType) => new
{
Type = type,
// to get all primitives, use SelectMany to flatten the elements in this group
Primitives = originalTypesThatHaveThisValueForType
.SelectMany(originalType => originalType.Primitives,
(originalType, primitive) => new
{
From = primitive.From,
To = primitive.To,
...
})
.ToList(),
});
换句话说:从您的原始类型序列中,创建具有相同属性类型值的类型组。
从您创建的每个组中,创建一个具有两个属性的对象:Type
和Primitives
。属性 Type 的值很简单:这是组中所有原始类型的共同值。
为了创建 property Primitives
,我们将组中的每个元素展平。请记住:该组是一组“带有原始类型的类型”(=原始类型)。我们使用 SelectMany 将其扁平化为 [原始类型,原始类型] 的组合。
因此,如果原始类型 A 具有基元 1、2、3;并且原始类型 B 具有原语 6、7,我们得到组合:
[A,原始 1] [A,原始 2] [A,原始 3] [B,原始 6] [B,原始 7]
我们将不再使用 A 和 B 中的任何内容,我们已经将它们的共同值用于属性类型。但我们对原语感兴趣:从组合中的每个原语中,我们制作一个对象:
// from every combination, make one new object:
(originalType, primitive) => new {...}
推荐阅读
- android - 无法制作小范围旋转动画
- excel - 在 VBA 中继续循环 sub1 到 sub 3
- kubernetes - pod 的 Azure CNI 动态 IP 分配如何工作?
- python - 路径中节点数固定的两个节点之间的最短路径
- java - Java str.split 使用 RegEx 返回空元素
- gitlab - 在本地托管的 gitlab 上引用对等存储库中的模块
- qgis - 跨其他层的字段计算器总和
- ethereum - 当与 eth 钱包发生交易时,是否有服务会调用 webhook
- java - 在java中存储数据问题
- node.js - NodeJS exec 与 Docker – 输入设备不是 TTY