你能帮忙吗,因为我无法为以下问题制定有条不紊的方法。
以下 xml 文档设置了按 ID 分组的人员记录。我想搜索一个节点,有条件地基于另外两个属性(MinAge,MaxAge)。一切正常,我可以根据 Id 和 Age 参数搜索特定节点。
<Group Id="189" Description="189 T1" MinAge="20" MaxAge="30"/>
<Group Id="189" Description="189 T2" MinAge="31" MaxAge="40"/>
<Group Id="190" Description="190 T1" MinAge="20" MaxAge="30"/>
<Group Id="190" Description="190 T2" MinAge="35" MaxAge="45"/>
<Group Id="190" Description="190 T3" MinAge="49" MaxAge="50"/>
<Group Id="191" Description="191 T1" MinAge="20" MaxAge="30"/>
<Group Id="193" Description="193 T1" MinAge="18" MaxAge="50"/>
var allGroup = XDocument.Parse("xml string");
var specificGroup =
allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id &&
int.Parse(e.Attribute("MinAge").Value) >= Age &&
int.Parse(e.Attribute("MaxAge").Value) <= Age)
问题:如果没有找到完全匹配,我想要的是返回一个紧密匹配的节点。即,假设如果我有一个搜索条件,其中 Id=189 且年龄为 35,那么输出节点将是描述为"189 T2"的节点。这很好,完全匹配。
现在假设如果我有一个搜索条件,其中 Id=190 且 Age 为 34,那么不会有任何输出节点,因为没有匹配的记录。但在这里,
我想返回一个描述为"190 T2"的节点,它非常接近 匹配,尽管它不完全匹配。
只是一些经典算法:
int target = 190; // target find value
int min = int.MaxValue;
Node best = null;
foreach (var node in nodes) {
int num = getNum(node.Describtion); // get the number from string
if (Math.Abs(target - num) < min) {
min = Math.Abs(target - num);
best = node;
}
}
这将引导您找到完全匹配的年龄(在本例中min == 0
),或者如果没有找到,则引导您找到最近的年龄(更大或更小)。结果最佳节点将位于变量best
。
这有点复杂,但这个应该做你想做的事。
var specificGroup = (allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id && int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value) >= Age).Any())
? allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id && int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value) >= Age)
: (allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id).Any())
? allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id).min(Math.Abs(Age - int.Parse(e.Attribute("MinAge").Value))+ Math.Abs(Age-int.Parse(e.Attribute("MaxAge").Value)))
: (allGroup.Descendants("Group").Where(e => int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value >= Age)).min(Math.Abs(Id - e.Id))).Any()
? allGroup.Descendants("Group").Where(e => int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value >= Age)).min(Math.Abs(Id - e.Id))
: allGroup.Descendants("Group").min(e => .min(Math.Abs(Age - int.Parse(e.Attribute("MinAge").Value))+ Math.Abs(Age-int.Parse(e.Attribute("MaxAge").Value)) + Math.Abs(Id - e.Id)));