我有一个Root-Parent-Child二叉树,需要根据几个条件求和并获取子值。我不确定是使用Linq还是遍历树。 Linq查询崩溃(Additional information: Unable to cast object of type 'ID' to type 'Greek'
),我不知道如何遍历树并检查每个参数。感谢您提供任何帮助,或链接到网站&书籍增加了我的知识。这link有所帮助,但我仍然陷入困境。
public class Node
{
public List<Node> Children = new List<Node>();
public Node Parent = null;
public Node(Node fromParent = null)
{
if (fromParent != null)
{
Parent = fromParent;
fromParent.Children.Add(this);
}
}
}
public class ID : Node
{
public int IdNo;
public int DealNo;
public string Strategy;
public ID(int _ID,int _DealNo,string _Strategy) : base(null)
{
IdNo = _ID;
DealNo = _DealNo;
Strategy = _Strategy;
}
}
public class Greek : Node
{
public string LegOrPos;
public string GreekType;
public Greek(string _LegOrPos, string _GreekType, Node fromParent = null) : base(fromParent)
{
LegOrPos = _LegOrPos;
GreekType = _GreekType;
}
}
public class DataPoint : Node
{
public int DpNo;
public double Value;
public DataPoint(int _DpNo, double _Value, Node fromParent = null) : base(fromParent)
{
DpNo = _DpNo;
Value = _Value;
}
}
public void SimpleTest()
{
List<Node> MC = new List<Node>();
// 1st node
var oID = new ID(23, 2,"Fly"); // ID,DealNo,Strategy
var oGreek = new Greek("Leg", "Delta", oID); //LegOrPos,GreekType
var oDP = new DataPoint(14, 0.235, oGreek); //DpNo,Value
MC.Add(oID);
// 2nd node
oID = new ID(25, 5,"BWB");
oGreek = new Greek("Leg", "Vega", oID);
oDP = new DataPoint(16, 0.345, oGreek);
MC.Add(oID);
// 3rd node
oID = new ID(31,2,"Fly");
oGreek = new Greek("Leg", "Delta", oID);
oDP = new DataPoint(14, 0.456, oGreek);
MC.Add(oID);
// use linq or traverse through tree?
// get total for several parameters
var Total = MC.Where(x => ((ID)x).DealNo == 2 && ((ID)x).Strategy == "Fly" && ((Greek)x).GreekType == "Delta" && ((DataPoint)x).DpNo == 14) // should sum 1st and 3rd nodes
.SelectMany(x => x.Children)
.Sum(x => ((DataPoint)x).Value);
// get specific value
var Val = Convert.ToDouble(MC.Where(x => ((ID)x).IdNo == 23 && ((Greek)x).GreekType == "Delta" && ((DataPoint)x).DpNo == 14) // should find 1st node
.SelectMany(x => x.Children)
.Select(x => ((DataPoint)x).Value).Single());
// traverse method
foreach (var objID in MC)
{
if (objID.IdNo == 23) //compile error-IdNo not found
{
foreach (Greek objGreek in objID.Children)
{
if (objGreek.GreekType == "Delta")
{
foreach (DataPoint objDP in objGreek.Children)
{
if (objDP.DpNo == 14)
{
double qVal = objDP.Value;
}
}
}
}
}
}
}
答案 0 :(得分:1)
你似乎遇到的问题是你的标准是不可能的。
这一行:MC.Where(x => ((ID)x).DealNo == 2 && ((ID)x).Strategy == "Fly" && ((Greek)x).GreekType == "Delta" && ((DataPoint)x).DpNo == 14)
。有人说,您希望MC
的每个成员同时属于ID
,Greek
和DataPoint
类型。
根据您的评论,您似乎需要这样:
var query =
from id in MC.OfType<ID>()
from greek in id.Children.OfType<Greek>()
from dp in greek.Children.OfType<DataPoint>()
group dp.Value by new
{
id.DealNo,
id.Strategy,
greek.LegOrPos,
greek.GreekType,
dp.DpNo
} into gs
select new
{
gs.Key,
Value = gs.Sum(),
};
当我在你的数据上运行时,我得到了这个:
答案 1 :(得分:0)
迭代列表的方法很少:
/// regular for
for (int L = 0; L <= MC.Count - 1; L++)
{
Node oID = MC[L];
if( oID == null ) continue;
/// oID is your node that you have added to the list MC
}
/// foreach
foreach ( var oID in MC.Where(_oID => _oID != null) )
{
/// oID is your node that you have added to the list MC
}
无论你走哪条路,我们刚收集到的oID
你也可以得到你的孩子节点:
foreach ( Greek oGreek in oID.Children.Where(_oGreek => _oGreek != null) )
{
/// use oGreeks that you've added to your oID node
///
foreach ( DataPoint oDP in oGreek.Children.Where(_oDP => _oDP != null) )
{
/// use oDP's that you've added to your greek node
}
}