你能帮忙吗,因为我无法找到解决问题的方法。
以下xml文档设置了按ID分组的人员记录。我想根据另外两个属性(MinAge,MaxAge)有条件地搜索节点。一切正常,我可以根据Id和年龄参数搜索特定节点。
<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且Age为35的搜索条件,那么输出节点将是具有描述&#39; 189 T2&#39;的节点。这很好,完全匹配。
现在假设我有一个Id = 190且Age为34的搜索条件,那么因为没有匹配的记录,所以不会有任何输出节点。但在这里,
我想返回一个带有描述&#39; 190 T2&#39;的节点,这是紧密的 但匹配虽然不完全匹配。
答案 0 :(得分:0)
只是一些经典算法:
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 节点将位于best
变量中。
答案 1 :(得分:0)
这有点令人费解,但是这个应该做你想要的。
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)));
&#13;