首页 > 解决方案 > 如何提取嵌套对象数组中“启用”对象的路径

问题描述

我是递归新手,我有一个带有嵌套对象数组的 JSON 结构。其中一些对象启用了布尔值:true。我试图弄清楚如何提取所有启用对象及其子对象的路径。

我尝试通过删除未使用的路径来清理原始对象,但我在访问父母时迷失了方向。我还尝试使用点符号构建一个单独的路径数组,因为我可能可以从中构建一个新的嵌套对象。我对点符号提取的最新尝试:


    const sourceData = {
      title: "Work",
      tags: [
        {
          title: "Cleaning",
          tags: [
            {
              title: "Floors"
            },
            { title: "Windows", enabled: true },
            { title: "Ceilings", enabled: true }
          ]
        },
        {
          title: "Maintenance",
          tags: [
            {
              title: "Walls",
              enabled: true,
              tags: [
                {
                  title: "Brickwall"
                },
                {
                  title: "Wooden wall"
                }
              ]
            },
            {
              title: "Roof"
            }
          ]
        },
        {
          title: "Gardening"
        }
      ]
    };

    function getEnabledPaths(level, acc) {
      for (const tag of level.tags) {
        if (tag.enabled) {
          return tag.title;
        } else if (tag.hasOwnProperty("tags")) {
          var path = this.getEnabledPaths(tag);
          if (path) acc.push(tag.title + "." + path);
        }
      }
      return acc;
    }

    console.log(getEnabledPaths(sourceData, []));

我只得到:

    [
      "Cleaning.Windows",
      "Maintenance.Walls"
    ]

理想情况下,我会得到这样的结果:

    [
      'Work.Cleaning.Windows',
      'Work.Cleaning.Ceilings',
      'Work.Maintenance.Walls.Brickwall',
      'Work.Maintenance.Walls.Wooden Wall'
    ]

在一个完美的世界中(但我尝试了几天并返回获取点符号结果):


    {
      title: "Work",
      tags: [
        {
          title: "Cleaning",
          tags: [
            {
              title: "Windows",
              enabled: true
            },
            {
              title: "Ceilings",
              enabled: true
            }
          ]
        },
        {
          title: "Maintenance",
          tags: [
            {
              title: "Walls",
              enabled: true,
              tags: [
                {
                  title: "Brickwall"
                },
                {
                  title: "Wooden wall"
                }
              ]
            }
          ]
        }
      ]
    };

标签: javascriptarraysrecursion

解决方案


enabled如果在某些较高级别上找到真值并且基于该结果的添加路径,您可以将参数向下传递到较低级别的递归。

const data ={"title":"Work","tags":[{"title":"Cleaning","tags":[{"title":"Floors"},{"title":"Windows","enabled":true},{"title":"Ceilings","enabled":true}]},{"title":"Maintenance","tags":[{"title":"Walls","enabled":true,"tags":[{"title":"Brickwall"},{"title":"Wooden wall"}]},{"title":"Roof"}]},{"title":"Gardening"}]}

function paths(data, prev = '', enabled = false) {
  const result = [];
  prev += (prev ? "." : '') + data.title;
  if (!enabled && data.enabled) enabled = true;

  if (!data.tags) {
    if (enabled) {
      result.push(prev);
    }
  } else {
    data.tags.forEach(el => result.push(...paths(el, prev, enabled)))
  }
  return result;
}

const result = paths(data)
console.log(result)


推荐阅读