根据条件和引用将集合拆分为对象
本文关键字:集合 拆分 对象 引用 条件 | 更新日期: 2023-09-27 18:25:58
给定以下数组(每个块[]表示一个条目):
[A=1] [A=5] [S=3] [A=7] [C=3] [T=2] [F=9] [Z=4] [N] [C=3] [E=8]
[A=7] [N] [Z=6] [Q=1] [P=2] [Y=7] [S=3] [N]
我需要将其拆分为类型为"N"(NObject)的对象,其中每隔一个字符表示该NObject对象的特定属性,直到下一次出现"N"为止。在第一次出现"N"之前,字符都属于另一个对象(我们称之为PObject)。因此,任务应满足以下要求:
- 将每个字符映射到PObject属性
- 当出现第一个"N"时,创建一个新的NObject
- 将每个字符映射到该NObject的属性
- 如果出现另一个N字符,请创建一个新的NObject
目前,在伪代码中,我的解决方案如下所示,我发现这还远远不够理想。
PObject pobject = new PObject();
NObject nobject;
CollectionOfKeyValuePairs collection = MyArray.Split('=').MapKeysValues()
foreach(entry in collection) {
switch(entry.Key):
case A:
(nobject ?? (CommonBase) pobject).A += entry.Value; break;
case B:
(nobject ?? (CommonBase) pobject).B += entry.Value; break;
case C:
(nobject ?? (CommonBase) pobject).C += entry.Value; break;
case E:
pobject.E += entry.Value; break;
case F:
(nobject ?? (CommonBase) pobject).F += entry.Value; break;
case G:
(nobject ?? (CommonBase) pobject).G += entry.Value; break;
case H:
(nobject ?? (CommonBase) pobject).H += entry.Value; break;
...
...
...
case N:
nobject = new NObject();
....
....
}
}
这正是我想要的:
[pobject]
A = 23
B = 63
C = 23
...
[nobject]
A = 34
B = 82
C = 12
...
[nobject]
H = 236
K = 2
...
[nobject]
// N occurred in array, but no properties followed
但是,有超过30个可能的属性标识符(意味着30个切换条件),并且仅根据nobject可能为null的事实分配了一个属性(并且每次出现"N"个字符都会创建一个新的):代码非常臭。但我不知道如何做不同的事情,也许是使用内置的集合函数、LINQ或其他任何东西。
您可以使用Dictionary来存储键值对,而不是为每个可能的情况显式地创建属性。类似于:
List<Dictionary<char,int>> listOfPNObjects = new List<Dictionary<char,int>>();
listOfPNObjects.Add(new Dictionary<char,int>()) //create default P dictionary
foreach(entry in collection) {
if(entry.Key == N)
{
listOfPNObjects.Add(new Dictionary<char,int>());
}
else
{
listOfPNObjects[listOfPNObjects.Count - 1].Add(entry.key, entry.value);
}
}
我已经使用反射和LINQ:重写了您的代码
var objects = keyValuePairList
.Aggregate<KeyValuePair<string, dynamic>, List<CommonBase>>(
new List<CommonBase>(), (a, p) =>
{
CommonBase cObject;
if (p.Key == "N")
{
cObject = new NObject();
a.Add(cObject);
}
if (a.Count == 0)
{
cObject = new PObject();
Process(p, ref cObject);
a.Add(cObject);
}
else
{
cObject = a.Last();
Process(p, ref cObject);
}
return a;
});
在Process
方法中,您可以根据属性的类型处理属性:
private static void Process(
KeyValuePair<string, dynamic> kvPair,
ref CommonBase cObject)
{
var propertyInfo = typeof(CommonBase).GetProperty(kvPair.Key);
switch (propertyInfo.PropertyType.FullName)
{
case "System.Int32":
propertyInfo
.SetValue(cObject,
(int)propertyInfo.GetValue(cObject) + (int)kvPair.Value);
break;
}
}