【问题标题】:How to find parent on recursive array如何在递归数组上找到父级
【发布时间】:2021-12-17 19:32:42
【问题描述】:

我想在递归数组中找到某项的父项

{
  "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a",
  "type": "page",
  "items": [
    {
      "uuid": "9d823429-cc24-444d-a21c-a81357305851",
      "title": "1",
      "type": "question",
    },
    {
      "type": "section",
      "title": "2",
      "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27",
      "items": [
        {
          "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f",
          "title": "2.1",
          "type": "question",
        }
      ],
    },
    {
      "type": "section",
      "title": "3",
      "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866",
      "items": [
        {
          "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3",
          "title": "3.1",
          "type": "question",
        }
      ],
    }
  ],
  "params": {
    "collapsed": false
  }
}

到目前为止我已经尝试过:

export const findItemParent = (items, id, parent = null) => {
  if (parent && parent.id === id) {
    return parent;
  }

  for (const item of items) {
    if (Object.prototype.hasOwnProperty.call(item, 'items')) {
      return findItemParent(item.items, id, item);
    }
  }

  return parent;
};

那我打电话给findItemParent

const data = [{...}]; // the data of the first snipet
// b2170580-1e2e-4fb4-a7b9-a56b79db21b3 -> item with title 3.1
const parent = findItemParent(data, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3");

每当我运行此代码时,我都会得到父级 2

Sandbox

在上面的例子中,我传递了标题为3.1 的项目的ID,所以逻辑上父级是3。如何获取给定 id 的任何项目的父项?

【问题讨论】:

  • 当您尝试运行此代码时发生了什么?
  • @ScottHunter 我已经更新了添加沙箱的问题。谢谢你告诉我

标签: javascript arrays recursion


【解决方案1】:

使用递归,这是我想出的。

参数items,我会说有点误导,我会使用像root这样的东西。

const findItemParent = (root, id, parent = null) => {
  if (root.uuid === id) return parent;
  if ('items' in root) {
    for (const i of root.items) {
      const r = findItemParent(i, id, root);
      if (r) return r;
    }
  }
  return null;
};

const data = {
  "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a",
  "type": "page",
  "items": [
    {
      "uuid": "9d823429-cc24-444d-a21c-a81357305851",
      "title": "1",
      "type": "question",
    },
    {
      "type": "section",
      "title": "2",
      "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27",
      "items": [
        {
          "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f",
          "title": "2.1",
          "type": "question",
        }
      ],
    },
    {
      "type": "section",
      "title": "3",
      "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866",
      "items": [
        {
          "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3",
          "title": "3.1",
          "type": "question",
        }
      ],
    }
  ],
  "params": {
    "collapsed": false
  }
};


const findItemParent = (root, id, parent = null) => {
  if (root.uuid === id) return parent;
  if ('items' in root) {
    for (const i of root.items) {
      const r = findItemParent(i, id, root);
      if (r) return r;
    }
  }
  return null;
};

const parent = findItemParent(data, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3");

if (parent) console.log(parent.title, parent.type, parent.uuid);

【讨论】:

    【解决方案2】:

    您可以使用递归函数来迭代每个项目的项目。

    const data = {
      "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a",
      "type": "page",
      "items": [
        {
          "uuid": "9d823429-cc24-444d-a21c-a81357305851",
          "title": "1",
          "type": "question",
        },
        {
          "type": "section",
          "title": "2",
          "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27",
          "items": [
            {
              "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f",
              "title": "2.1",
              "type": "question",
            }
          ],
        },
        {
          "type": "section",
          "title": "3",
          "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866",
          "items": [
            {
              "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3",
              "title": "3.1",
              "type": "question",
            }
          ],
        }
      ],
      "params": {
        "collapsed": false
      }
    };
    
    function findItemParent(items, id, parent = null) {
      if (items.find(item => item.uuid === id)) return { uuid: parent?.uuid, type: parent?.type, title: parent?.title };
      for (const item of items) {
        let p;
        if (item.type === 'section') {
          p = findItemParent(item.items, id, item);
        }
        if (p) return p;
      }
    }
    
    console.log(findItemParent(data.items, "b2170580-1e2e-4fb4-a7b9-a56b79db21b3"));

    【讨论】:

    • OP 确实使用了递归函数,只是没有使用。
    【解决方案3】:

    我会制作一张地图,您可以在其中引用树中的父级。如果您有很多查找,这将很有帮助。

    const book = {
      "uuid": "707a5ffd-68e2-4dbd-b539-128512ba3a0a",
      "type": "page",
      "items": [
        {
          "uuid": "9d823429-cc24-444d-a21c-a81357305851",
          "title": "1",
          "type": "question",
        },
        {
          "type": "section",
          "title": "2",
          "uuid": "346dec94-124c-4932-bd40-af9dc68f1d27",
          "items": [
            {
              "uuid": "bf0a9ab9-99cc-4833-b3d3-84a97072e85f",
              "title": "2.1",
              "type": "question",
            }
          ],
        },
        {
          "type": "section",
          "title": "3",
          "uuid": "4964096d-0de9-4ab1-ace5-e42516d6b866",
          "items": [
            {
              "uuid": "b2170580-1e2e-4fb4-a7b9-a56b79db21b3",
              "title": "3.1",
              "type": "question",
            }
          ],
        }
      ],
      "params": {
        "collapsed": false
      }
    };
    
    function walkTree(group, parentRef, titleMapping) {
      titleMapping = titleMapping || {}; 
      group.items.forEach(function (item) {
        titleMapping[item.title] = { ...item, parentRef };
        if (item.items) walkTree(item, titleMapping[item.title], titleMapping);
      });
      return titleMapping;
    }
    
    const titleMapping = walkTree(book);
    console.log(titleMapping["3.1"].parentRef.title);

    其他选项是使用递归查找来查看项目是否包含标题。

    【讨论】:

      【解决方案4】:
      const findParent = (currentObject, id, parent = null) => {
      
        // If its found return its parent
        if (currentObject.uuid === id) return parent;
      
        // Iterate through sub items 
        for (const item of (currentObject.items) || []) {
      
          // If found return it
          const found = findParent(item, id, currentObject);
          if (found) return found;
      
        }
        // If not found return null;
        return null;
      
      };
      
      findParent(el, "346dec94-124c-4932-bd40-af9dc68f1d27");
      

      【讨论】:

        猜你喜欢
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 1970-01-01
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        相关资源
        最近更新 更多