我正在使用无限级结构,类似于此:
{
"name": "Group1",
"type": "group",
"nodes": [
{
"name": "Node1",
"type": "node",
"someproperty": "somevalue1"
},
{
"name": "Group2",
"type": "group",
"nodes": [
{
"name": "Node2",
"type": "node",
"someproperty": "somevalue2"
},
{
"name": "Node3",
"type": "node",
"someproperty": "somevalue3"
}
]
}
]
}
我们可以在组内有节点,也可以在组内有组。
到目前为止,每次需要做某件事时,我就一直在编写递归函数,但是代码变得非常古怪。
我想知道是否有一种方法可以创建Array.prototype方法的版本,但可以自定义它们以使用递归
例如,通过ID查找任何对象(节点或组),我有一个方法
findNode(target, thisGroup) {
if (typeof thisGroup == "undefined") {
thisGroup = this;
}
// Am I the element?
if (thisGroup.id == target) {
return thisGroup;
}
// Look for element in my nodes
var elementIx = thisGroup.nodes.findIndex(e => e.id == target);
if (elementIx > 0) {
// Found the element - return it
return thisGroup.nodes[elementIx];
}
// Not found. Do I contain a group?
var elementIx = thisGroup.nodes.findIndex(e => e.type == "group");
if (elementIx > 0) {
var nestGroup = thisGroup.nodes[elementIx];
// If so, nest into this group and look again
return this.findValue(target, nestGroup)
}
}
在现实世界中,我需要搜索/嵌套的不只是Id
。那么如何创建自己的原型函数,然后可以像这样调用呢?
thisGroup.nodes.findIndexRecursively(e => e.id == target)
thisGroup.nodes.findIndexRecursively(e => e.type=="node" && e.someProp == someValue)
答案 0 :(得分:2)
我个人不会将其添加到原型中,只需一个简单的函数即可。
这是一个简单的示例,它假设您要递归遍历并检查所有数组。
const data = [{"name":"Group1","type":"group","nodes":[{"name":"Node1","type":"node","someproperty":"somevalue1"},{"name":"Group2","type":"group","nodes":[{"name":"Node2","type":"node","someproperty":"somevalue2"},{"name":"Node3","type":"node","someproperty":"somevalue3"}]}]}];
function rfind(arr, callback) {
for (const a of arr) {
const f = callback(a);
if (f) return a;
if (!f) {
for (const o of Object.values(a)) {
if (Array.isArray(o)) {
const f2 = rfind(o, callback);
if (f2) return f2;
}
}
}
}
}
console.log(rfind(data, f => f.name==="Node1"));
console.log(rfind(data, f => f.name==="Node3"));
答案 1 :(得分:1)
您可以使用递归函数并使用回调进行查找。
function find(node, cb) {
var result;
if (cb(node)) return node;
if (node.nodes) node.nodes.some(o => result = find(o, cb));
return result;
}
var node = { name: "Group1", type: "group", nodes: [{ name: "Node1", type: "node", someproperty: "somevalue1" }, { name: "Group2", type: "group", nodes: [{ name: "Node2", type: "node", someproperty: "somevalue2" }, { name: "Node3", type: "node", someproperty: "somevalue3" }] }] },
find1 = find(node, ({ type, someproperty }) => type === 'node' && someproperty === 'somevalue2'),
find2 = find(node, ({ name, type }) => name === 'Group2' && type === 'group');
console.log(find1);
console.log(find2);
.as-console-wrapper { max-height: 100% !important; top: 0; }