递归使用数组原型方法

问题描述 投票:1回答:2

我正在使用无限级结构,类似于:

    {
  "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)
javascript arrays es6-class
2个回答
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
投票

您可以使用递归函数并使用回调进行搜索。

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; }
© www.soinside.com 2019 - 2024. All rights reserved.