次のようなJSONオブジェクト構造で特定のノードを返そうとしています
_{
"id":"0",
"children":[
{
"id":"1",
"children":[...]
},
{
"id":"2",
"children":[...]
}
]
}
_
したがって、これはツリーのような子親関係です。すべてのnodeには一意のIDがあります。特定のnodeを見つけようとしています
_function findNode(id, currentNode) {
if (id == currentNode.id) {
return currentNode;
} else {
currentNode.children.forEach(function (currentChild) {
findNode(id, currentChild);
});
}
}
_
たとえばfindNode("10", rootNode)
で検索を実行します。ただし、検索で一致が見つかった場合でも、関数は常にundefined
を返します。私は、一致を見つけた後、再帰関数が停止せず、最後にundefined
を実行し続けるという悪い感じがあります。なぜなら、後者の再帰実行では、戻り点に到達しないからです。これを修正する方法。
助けてください!
再帰的に検索する場合、結果を返すことで結果を返さなければなりません。ただし、findNode(id, currentChild)
の結果は返されません。
function findNode(id, currentNode) {
var i,
currentChild,
result;
if (id == currentNode.id) {
return currentNode;
} else {
// Use a for loop instead of forEach to avoid nested functions
// Otherwise "return" will not work properly
for (i = 0; i < currentNode.children.length; i += 1) {
currentChild = currentNode.children[i];
// Search in the current child
result = findNode(id, currentChild);
// Return the result if the node has been found
if (result !== false) {
return result;
}
}
// The node has not been found and we have no more options
return false;
}
}
function findNode(id, currentNode) {
if (id == currentNode.id) {
return currentNode;
} else {
var result;
currentNode.children.forEach(function(node){
if(node.id == id){
result = node;
return;
}
});
return (result ? result : "No Node Found");
}
}
console.log(findNode("10", node));
このメソッドは、ノードリストにノードが存在する場合、そのノードを返します。ただし、forEach
フローを正常に分割できないため、ノードのすべての子をループします。より良い実装は以下のようになります。
function findNode(id, currentNode) {
if (id == currentNode.id) {
return currentNode;
} else {
for(var index in currentNode.children){
var node = currentNode.children[index];
if(node.id == id)
return node;
findNode(id, node);
}
return "No Node Present";
}
}
console.log(findNode("1", node));
私は次を使用します
var searchObject = function (object, matchCallback, currentPath, result, searched) {
currentPath = currentPath || '';
result = result || [];
searched = searched || [];
if (searched.indexOf(object) !== -1 && object === Object(object)) {
return;
}
searched.Push(object);
if (matchCallback(object)) {
result.Push({path: currentPath, value: object});
}
try {
if (object === Object(object)) {
for (var property in object) {
if (property.indexOf("$") !== 0) {
//if (Object.prototype.hasOwnProperty.call(object, property)) {
searchObject(object[property], matchCallback, currentPath + "." + property, result, searched);
//}
}
}
}
}
catch (e) {
console.log(object);
throw e;
}
return result;
}
その後、書くことができます
searchObject(rootNode, function (value) { return value != null && value != undefined && value.id == '10'; });
現在、これは循環参照で機能し、matchCallback
関数を変更することにより、任意のフィールドまたはフィールドの組み合わせで一致させることができます。
私はツリー検索が本当に好きでした!ツリーは、今日の複雑な構造化タスクのほとんどにとって非常に一般的なデータ構造です。だから、昼食にも同じような仕事をしました。私もいくつかの深い研究をしましたが、実際には新しいものを発見していません!それで、今日私が得たものは、「現代のJS構文でどのように実装したか」です。
// helper
find_subid = (id, childArray) => {
for( child of childArray ) {
foundChild = find_id( i, child ); // not sub_id, but do a check (root/full search)!
if( foundChild ) // 200
return foundChild;
}
return null; // 404
}
// actual search method
find_id = (id, parent) => (id == parent.id) : parent : find_subid(id, parent.childArray);