【问题标题】:Get directory path in Array of Objects from directory path as string从目录路径获取对象数组中的目录路径作为字符串
【发布时间】:2018-06-21 21:09:47
【问题描述】:

一直在搜索 SO 帖子,但没有人能回答我这个问题。

我有一个这样的文件夹数组:

[{
"name": "home",
"folders": [{
    "name": "New Folder",
    "folders": [{
        "name": "53w5r",
        "folders": [{
            "name": "test",
            "folders": []
        }]
    }]
}, {
    "name": "public folder",
    "folders": [{
        "name": "cold",
        "folders": []
    }, {
        "name": "hot",
        "folders": []
    }]
}, {
    "name": "My Folder",
    "folders": []
}]

}]

我需要使用如下的路径字符串来搜索这个数组:

"home,New Folder,53w5r,test"

我正在搜索该文件夹,因此 findFolder 方法将获取上面的字符串并返回“test”文件夹中的文件夹对象。

【问题讨论】:

  • 您的问题不清楚,能否重新表述一下?
  • 技术上不应该是"home,New Folder,53w5r,test"吗?
  • 是的!谢谢..已编辑。
  • @Jason 我已经更新了我的答案。它现在显示正确的输出。

标签: javascript arrays recursion


【解决方案1】:

假设您的逗号分隔路径始终有效,您可以使用这种简单的方法来遍历数据:

var str = "home,New Folder,53w5r,test";
var data = [{
  "name": "home",
  "folders": [{
    "name": "New Folder",
    "folders": [{
      "name": "53w5r",
      "folders": [{
        "name": "test",
        "folders": []
      }]
    }]
  }, {
    "name": "public folder",
    "folders": [{
      "name": "cold",
      "folders": []
    }, {
      "name": "hot",
      "folders": []
    }]
  }, {
    "name": "My Folder",
    "folders": []
  }]
}];

var folderNames = str.split(",");
var result = folderNames.reduce((results, folderName, index) => {
  var currFolder = results.find(folder => folder.name === folderName);
  // if last folder, return entire folder, otherwise return currFolder.folders
  return index === folderNames.length-1 ? currFolder : currFolder.folders;
}, data);
console.log(result);

【讨论】:

    【解决方案2】:

    这是我没有reduce的实现,如果找不到目录,它将返回null。

    const dirSeperator = ",";
    
    function findDir(path, dirs) {
      var parts = path.split(dirSeperator);
    
      if (parts && parts.length > 0) {
        var n = parts[0];
        for (var i = 0; i < dirs.length; i++) {
          if (dirs[i].name === n) {
            if (parts.length > 1)
              return findDir(path.replace(n + dirSeperator, ''), dirs[i].folders)
            else if (parts.length == 1)
              return dirs[i]
          }
        }
    
        return null;
      } else {
        return null;
      }
    }
    
    var dirs = [{
        "name": "Test",
        "folders": [{
          "name": "Test2",
          "folders": [{
              "name": "test 3",
              "folders": []
            },
            {
              "name": "test 3",
              "folders": []
            }
          ]
        }]
      },
      {
        "name": "Main",
        "folders": [{
          "name": "Test2",
          "folders": [{
              "name": "test 3",
              "folders": []
            },
            {
              "name": "test 3",
              "folders": []
            }
          ]
        }]
      }
    ];
    const testcase = "Test,Test2,test 3";
    console.log('Searching for', testcase, ' in ', dirs)
    console.log(findDir(testcase, dirs))

    【讨论】:

    • @Ivan pft,它很难写,所以它应该同样难以阅读;)递归总是很有趣
    【解决方案3】:

    这是一个 2 行解决方案:

    您可以使用.find方法在层级上搜索文件夹:

    (folder, name) => folder.folders.find(e => e.name == name);
    

    然后我编写了一个递归函数,它将查找所提供路径的每个元素的文件夹。它使用.reduce 来跟踪父文件夹(acc)。在循环结束时,它返回最后一个文件夹数组(路径末尾的那个)。

    path.split(',').reduce((acc, curr) => find(acc, curr), {folders:folders});
    

    这是一个快速演示:

    const find = (folder, name) => folder.folders.find(e => e.name == name);
    
    const getFolders = path => path.split(',').reduce((acc, curr) => find(acc, curr), {folders:folders});
    
    console.log(
      getFolders('home,New Folder,53w5r,test')
    );
    <script>
    const folders = [{
      "name": "home",
      "folders": [{
        "name": "New Folder",
        "folders": [{
          "name": "53w5r",
          "folders": [{
            "name": "test",
            "folders": []
          }]
        }]
      }, {
        "name": "public folder",
        "folders": [{
          "name": "cold",
          "folders": []
        }, {
          "name": "hot",
          "folders": []
        }]
      }, {
        "name": "My Folder",
        "folders": []
      }]
    }]
    </script>

    【讨论】:

    • OP 希望文件夹对象本身位于末尾,而不是 folders 数组中的内容(因为它可能是空的,如果这些不是您正在寻找的内容,它并没有太大帮助为了)。这也是我发布的答案的一个不太冗长但可读性较差的版本。
    • just a less-verbose but less-readable version of my answer,太好了!我喜欢 Stack Overflow 的用户。你需要一些练习来阅读这段代码,我会给你,但我不认为它不可读。我使用函数来分隔不同的任务。 acc 和 curr 不需要其他名称。这是一个品味问题。
    • @Ivan SO 的一部分是帮助其他人理解。将所有内容都集中在一行上可能会显示您的 JS 能力,但对于大多数提出问题的人来说,这只是行话。一个完美的例子是单线.reduce()。需要花费额外的时间来确定返回的确切内容,因为末尾的逗号可以是逗号运算符,也可以是分隔参数。这不是很清楚,您必须花费额外的时间来梳理其余代码以确保逗号的使用方式。
    • @Ivan 请记住,源代码不是为计算机编写的,这一点很重要。我们为开发人员编写源代码。有时(并非总是)冗长是一件好的事情。您的计算机将负责去除空白、缩小、混淆和解释代码。
    • @mhodges 很公平,你已经表达了你的观点,我同意。优雅的代码虽然很好。另外,我不喜欢你处理讨论的方式......无论如何
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2017-10-11
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2011-02-14
    相关资源
    最近更新 更多