过滤树结构
Filter tree structure
我正在尝试遍历一棵树,但不知何故我似乎无法让它像我想要的那样工作。
我得到了一个带整数的过滤器(由用户选择)
节点看起来像:
- Id: Int
- ParentId: Int
- Children: { 节点(Objects) }
我的树:
树(根)
- Child
- Child (ID:1)
- Child
- Child
- Child (ID:2)
- Child
- Child
- Child (ID:3)
- Child
- Child (ID:4)
- Child
- Child
- Child (ID:5)
- Child
- Child
- Child
我想以这样的方式结束。所选节点的每个节点 + 所选节点的 parents 一直到顶部。
树(根)
- Child
- Child (ID:1)
- Child
- Child (ID:2)
- Child (ID:3)
- Child
- Child (ID:4)
- Child (ID:5)
我目前的解决方案是这样的
organizationIterator = (node, filter, parent, result) ->
_.each(node, (leaf)->
tempLeaf = _.clone(leaf)
tempIndex = filter.indexOf(leaf.organizationId)
if tempIndex > -1
if result[leaf.parentOrganizationId]
tempLeaf.subOrganizations = []
parent.subOrganizations.push tempLeaf
result[parent.organizationId] = parent
else
result[leaf.organizationId] = tempLeaf
else
tempLeaf.notSelected = true
if leaf.subOrganizations
tempLeaf.subOrganizations = []
organizationIterator(leaf.subOrganizations, filter, tempLeaf, result)
)
希望有人能指导我找到可行的解决方案。
我不知道你在 Coffeescript 中是怎么做的,但在常规 Javascript 中它看起来像下面这样。希望这能为您提供一个开始:
//setup
var input = document.getElementById('filter'),
tree = document.getElementById('tree'),
selectedValues = [],
items = tree.getElementsByTagName('li'), afterInsert;
for (var i = 0; i < items.length; i++) {
afterInsert = items[i].firstChild.nextSibling;
items[i].setAttribute('data-id', i);
items[i].insertBefore(document.createTextNode(' ' + (i+1)), afterInsert);
}
input.addEventListener('change', function() {
selectedValues = input.value.split(',');
var count = /[0-9]/g.test(input.value) ? selectedValues.length : items.length;
// if input is non-empty
if (/[0-9]/g.test(input.value)) {
// make the selected values from input of type number and zero-based
while (count--)
selectedValues[count] = parseInt(selectedValues[count]-1);
// THE RECURSIVE FUNCTION
function addParent(node) {
var index = parseInt(node.getAttribute('data-id'));
if (node.nodeName == 'LI') {
// only add an index if it's not already present
if (selectedValues.indexOf(index) === -1)
selectedValues.push(index);
addParent(node.parentNode.parentNode);
}
}
for (var i = selectedValues.length; i--;) {
addParent(items[selectedValues[i]]);
}
// if input is empty, set all items to 'selectedValues'
} else {
while (count--)
selectedValues.push(count);
}
for (var i = items.length; i--;) {
if (selectedValues.indexOf(i) !== -1)
items[i].style.display = 'list-item';
else
items[i].style.display = 'none';
}
}, false);
<p>Write different numbers as comma-separated into the input field</p>Filter: <input type="text" id="filter">
<ul id="tree">
<li>item</li>
<li>item
<ul>
<li>item</li>
<li>item
<ul>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
<li>item
<ul>
<li>item
<ul>
<li>item</li>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
</ul>
我正在尝试遍历一棵树,但不知何故我似乎无法让它像我想要的那样工作。
我得到了一个带整数的过滤器(由用户选择)
节点看起来像:
- Id: Int
- ParentId: Int
- Children: { 节点(Objects) }
我的树:
树(根)
- Child
- Child (ID:1)
- Child
- Child
- Child (ID:2)
- Child
- Child
- Child
- Child (ID:3)
- Child
- Child (ID:4)
- Child
- Child
- Child (ID:4)
- Child (ID:5)
- Child
- Child (ID:1)
- Child
- Child
- Child
我想以这样的方式结束。所选节点的每个节点 + 所选节点的 parents 一直到顶部。
树(根)
- Child
- Child (ID:1)
- Child
- Child (ID:2)
- Child
- Child (ID:3)
- Child
- Child (ID:4)
- Child (ID:5)
- Child
- Child (ID:1)
我目前的解决方案是这样的
organizationIterator = (node, filter, parent, result) ->
_.each(node, (leaf)->
tempLeaf = _.clone(leaf)
tempIndex = filter.indexOf(leaf.organizationId)
if tempIndex > -1
if result[leaf.parentOrganizationId]
tempLeaf.subOrganizations = []
parent.subOrganizations.push tempLeaf
result[parent.organizationId] = parent
else
result[leaf.organizationId] = tempLeaf
else
tempLeaf.notSelected = true
if leaf.subOrganizations
tempLeaf.subOrganizations = []
organizationIterator(leaf.subOrganizations, filter, tempLeaf, result)
)
希望有人能指导我找到可行的解决方案。
我不知道你在 Coffeescript 中是怎么做的,但在常规 Javascript 中它看起来像下面这样。希望这能为您提供一个开始:
//setup
var input = document.getElementById('filter'),
tree = document.getElementById('tree'),
selectedValues = [],
items = tree.getElementsByTagName('li'), afterInsert;
for (var i = 0; i < items.length; i++) {
afterInsert = items[i].firstChild.nextSibling;
items[i].setAttribute('data-id', i);
items[i].insertBefore(document.createTextNode(' ' + (i+1)), afterInsert);
}
input.addEventListener('change', function() {
selectedValues = input.value.split(',');
var count = /[0-9]/g.test(input.value) ? selectedValues.length : items.length;
// if input is non-empty
if (/[0-9]/g.test(input.value)) {
// make the selected values from input of type number and zero-based
while (count--)
selectedValues[count] = parseInt(selectedValues[count]-1);
// THE RECURSIVE FUNCTION
function addParent(node) {
var index = parseInt(node.getAttribute('data-id'));
if (node.nodeName == 'LI') {
// only add an index if it's not already present
if (selectedValues.indexOf(index) === -1)
selectedValues.push(index);
addParent(node.parentNode.parentNode);
}
}
for (var i = selectedValues.length; i--;) {
addParent(items[selectedValues[i]]);
}
// if input is empty, set all items to 'selectedValues'
} else {
while (count--)
selectedValues.push(count);
}
for (var i = items.length; i--;) {
if (selectedValues.indexOf(i) !== -1)
items[i].style.display = 'list-item';
else
items[i].style.display = 'none';
}
}, false);
<p>Write different numbers as comma-separated into the input field</p>Filter: <input type="text" id="filter">
<ul id="tree">
<li>item</li>
<li>item
<ul>
<li>item</li>
<li>item
<ul>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
<li>item
<ul>
<li>item
<ul>
<li>item</li>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
</ul>