可以使用matchedset.find(selector)/ matchedset.parents(selector)来获取由选择器过滤的当前匹配集的后代/祖先,但是不包括匹配集本身(如果它恰好也匹配选择器).是否有更好的(更简洁和/或更快)的方式来获得它
matchedset.find(selector).add(matchedset.filter(selector))
Run Code Online (Sandbox Code Playgroud)
和父母的相应()?
请考虑以下HTML:
<div class="foo" id="obj">
I should be changed red
<div class="bar" style="color:black;">
I should not be changed red.
<div class="foo">I should be changed red.</div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
给定一个DOM元素obj和一个表达式,我该如何选择任何一个孩子obj?我正在寻找类似于"选择后代"的东西,但如果它与表达式匹配,还包括父级.
var obj = $("#obj")[0];
//wrong, may include siblings of 'obj'
$(".foo", $(obj).parent()).css("color", "red");
//wrong -- excludes 'obj'
$(".foo", obj).css("color", "red");
//correct way, but it's annoying
var matches = $(".foo", obj);
if ($(obj).is(".foo")) matches = matches.add(obj);
matches.css("color", "red");
Run Code Online (Sandbox Code Playgroud)
有更优雅的解决方案吗?
我想构造一个XPath查询,它将返回一个"div"或"table"元素,只要它有一个包含文本"abc"的后代.一个警告是它不能有任何div或table后代.
<div>
<table>
<form>
<div>
<span>
<p>abcdefg</p>
</span>
</div>
<table>
<span>
<p>123456</p>
</span>
</table>
</form>
</table>
</div>
Run Code Online (Sandbox Code Playgroud)
所以这个查询唯一正确的结果是:
/div/table/form/div
Run Code Online (Sandbox Code Playgroud)
我最好的尝试看起来像这样:
//div[contains(//text(), "abc") and not(descendant::div or descendant::table)] | //table[contains(//text(), "abc") and not(descendant::div or descendant::table)]
Run Code Online (Sandbox Code Playgroud)
但不会返回正确的结果.
谢谢你的帮助.
我试图让所有descendants(include_self=True)不是一个节点,而是一个节点列表(一个QuerySet).这应该是一个SQL查询.
示例(实际上不起作用:)
some_nodes = Node.objects.filter( ...some_condition... )
some_nodes.get_descendants(include_self=True) #hopefully I would like
to have all possible Nodes starting from every node of "some_nodes"
Run Code Online (Sandbox Code Playgroud)
我现在唯一的想法是遍历some_nodes并为每个节点运行get_descendants() - 但这是一个非常糟糕的解决方案(大量的SQL查询).
如果没有干净的方法通过Django ORM这样做,你可以提供一个自定义SQL来运行吗?在这里你可以假设我有一个Node的pk列表.
编辑:如果这可以帮助 - 我的所有"some_nodes"都放在同一个父目录中,并在树中具有相同的"级别".
想象一下以下的树:
A
/ \
B C
/ \ \
D E F
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种方法来查询例如F是否是A的后代(注意:F不需要是F 的直接后代),在这种情况下,这将是真的.只需要针对较大的潜在后代节点池测试有限数量的潜在父节点.
更新:在测试节点是否是潜在父池中节点的后代时,需要针对所有潜在父节点对其进行测试.
这是一个想法:
将多路树转换为trie,即将以下前缀分配给上述树中的每个节点:
A = 1
B = 11
C = 12
D = 111
E = 112
F = 121
Run Code Online (Sandbox Code Playgroud)然后,为每个可能的前缀大小保留一个位数组,并添加要测试的父节点,即如果将C添加到潜在的父节点池,请执行以下操作:
1 2 3 <- Prefix length
*[1] [1] ...
[2] *[2] ...
[3] [3] ...
[4] [4] ...
... ...
Run Code Online (Sandbox Code Playgroud)当测试节点是否是潜在父节点的后代时,取其trie前缀,查找第一个"前缀数组"中的第一个字符(见上文),如果存在,则在第二个"前缀中查找第二个前缀字符数组"依此类推,即测试F导致:
F = 1 2 1
*[1] [1] ...
[2] *[2] ...
[3] [3] ...
[4] [4] ...
... ...
Run Code Online (Sandbox Code Playgroud)
所以是的,F是C.的后代.
这个测试似乎是最坏的情况O(n),其中n …
如果您使用gitk --all,您可以从所有分支机构查看您的仓库的所有提交.除了给定提交的后代之外,我想要这样的东西.
从 Python 3.5 开始,您可以使用PEP-0484 中描述的泛型和其他有趣的东西。我试过了,这是我的代码:
from typing import TypeVar, Generic, Optional
...
_T = TypeVar('T')
_S = TypeVar('S')
class Pool(Generic[_S, _T]):
def __init__(self) -> None:
self.pool = dict()
... getters and setters here...
Run Code Online (Sandbox Code Playgroud)
这段代码完美地工作并完成了预期的工作。然后我决定扩展这个类来做一些额外的工作。我就是这样做的:
class PoolEx(Pool[_S, _T]):
ARGUMENTS = []
def __init__(self) -> None:
print("self=", self, self.__class__.__bases__)
super(PoolEx, self).__init__()
self.arguments_pool = dict()
... other code here ...
Run Code Online (Sandbox Code Playgroud)
为了测试Pool我创建的类MyPool,它看起来像这样:
class MyPool(Pool[str, Hello]):
pass
Run Code Online (Sandbox Code Playgroud)
然后我放了类似的东西mypool = MyPool(),效果很好。实施后PoolEx,我已更新MyPool为:
class MyPool(PoolEx[str, Hello]): …Run Code Online (Sandbox Code Playgroud) 我需要得到所有后代用side_a - side_b(在一个数据帧中)表示的链接,直到达到每个side_a他们的end_point(在其他数据帧中).所以:
df1:
side_a side_b
a b
b c
c d
k l
l m
l n
p q
q r
r s
df2:
side_a end_point
a c
b c
c c
k m
k n
l m
l n
p s
q s
r s
Run Code Online (Sandbox Code Playgroud)
关键是获取每个side_a值的所有点,直到从df2到达该值的end_point.如果它有两个end_point值(如"k"那样),它应该是两个列表.
我有一些代码,但它不是用这种方法编写的,它会从df1中删除所有行,如果df1['side_a'] == df2['end_points']这会导致某些问题.但是,如果有人要我发布代码,我当然会.
期望的输出将是这样的:
side_a end_point
a [b, c]
b [c]
c [c]
k [l, m]
k [l, n]
l [m]
l [n]
p [q, r, s]
q [r, s] …Run Code Online (Sandbox Code Playgroud) 我有一个任意的树结构.
root
|--node1
| |--node2
| | |--leaf1
| |
| |--leaf2
|
|--node3
|--leaf3
Run Code Online (Sandbox Code Playgroud)
每个节点和叶子有2个属性:id和name.
1.:给出了一个叶子id.查询应该返回从root到该leaf的整个路径,包含所有节点id和name属性.
如果返回值是排序的节点数组,或者它是嵌套节点的对象,那么这一点并不重要.
示例:如果给出了idof leaf2,则查询应返回:root(id, name), node1(id, name), leaf2(id, name).
2.:给定任何节点id:获取整个(子)树.在这里检索每个节点都有一个children数组的单个对象会很不错.
1.:首先,我尝试将树简单地建模为单个JSON文档,但随后查询将变得不可能:无法找出叶子的嵌套级别.如果我知道id从根到叶子的整个路径,我必须使用具有多个位置运算符的投影,而MongoDB目前不支持.此外,不可能对叶子进行索引,ids因为嵌套可以是无限的.
2.:下一个想法是使用平面数据设计,其中每个节点都有一个包含节点祖先的数组ids:
{
id: ...,
name: ...,
ancestors: [ rootId, node1Id, ... ]
}
Run Code Online (Sandbox Code Playgroud)
这样我就必须做2个查询,以获得从root到某个节点或叶子的整个路径,这非常好.
如果我选择数据模型2.:我如何获得整个树或子树?
获得所有后代很容易:find({ancestors:"myStartingNodeId"}).但那些当然不会被排序或嵌套.
有没有办法使用聚合框架或完全不同的数据模型来解决这个问题? …
好吧,我想我使用以下方法解决了它(禁止边缘情况):
function findByDepth(parent, child, depth){
var children = $();
$(child, $(parent)).each(function(){
if($(this).parentsUntil(parent, child).length == (depth - 1)){
children = $(children).add($(this));
}
});
return children;
}
// this would successfully return the 3.X elements of an HTML snippet structured
// as my XML example, where <parent> = #parent, etc.
var threeDeep = findByDepth('#parent', '.child', 3);
Run Code Online (Sandbox Code Playgroud)
然而,有人必须在这里得到接受的答案,我不打算自己回答这个问题,并且与你赚得很好的代表潜逃.所以,如果有人想添加任何东西,如洞察优化此功能(之前我去和$.extend()它)我很可能标志着你的答案正确,否则回落到标记谁是第一对我最初的问题.
顺便说一句,请在小提琴中查看:http://jsfiddle.net/5PDaA/
分更新
再看看@ CAFxX的答案,我意识到他的方法可能更快,利用querySelectorAll可以的浏览器.无论如何,我修改了他对下面的方法,但它仍然让我感到愤怒:
$.fn.extend({
'findAtDepth': function(selector, depth){
var …Run Code Online (Sandbox Code Playgroud)