【问题标题】:How to walk through directory in Erlang to take only folders?如何遍历 Erlang 中的目录以仅获取文件夹?
【发布时间】:2020-12-30 17:20:16
【问题描述】:
-module(tut).
-export([main/0]).

main() -> 

    folders("C:/Users/David/test/").
    

folders(PATH) ->
    {_,DD} = file:list_dir(PATH),
    A = [{H,filelib:is_dir(PATH ++ H)}|| H <-DD],
    % R is a list of all folders inside PATH
    R = [PATH++X|| {X,Y} <- A, Y =:= true],
    io:fwrite("~p~n", [R]),
    case R of
        [] -> ok;
        % How call again folders function with the first element of the list?
        % And save the result in some kind of structure 
    end.

对于初学者的问题,我很抱歉,但我还是 Erlang 的新手。我想知道如何再次调用该函数,直到将结果保存在一种列表、元组或结构中......

喜欢:

  [
    {"C:/Users/David/test/log", 
      {"C:/Users/David/test/log/a", "C:/Users/David/test/log/b"}},
    {"C:/Users/David/test/logb", 
      {"C:/Users/David/test/logb/1", "C:/Users/David/test/logb/2","C:/Users/David/test/logb/3"}},
 ]  

【问题讨论】:

    标签: erlang


    【解决方案1】:

    几件事:

    1. 这两个调用可以简化。
    A = [{H,filelib:is_dir(PATH ++ H)}|| H <-DD],
    R = [PATH++X|| {X,Y} <- A, Y =:= true],
    

    进入

    A = [H || H <- DD, filelib:is_dir(PATH ++ H) =:= true],
    
    1. 在表示方面,子文件夹应该是列表格式,而不是元组。如果它们是元组,将很难使用。 示例结构:{Folder, [Subfolder1, Subfolder2, ...]},其中SubfolderX 将具有相同的定义和结构,递归
    2. 文件夹就像树,所以这里需要递归调用。希望你已经熟悉这个概念。以下是使用列表理解的一种方法 - 无论如何还有其他方法,例如通过使用lists:foldl 函数。
    folders(PATH) ->
        {_, DD} = file:list_dir(PATH), 
        A = [H || H <- DD, filelib:is_dir(PATH ++ "/" ++ H) =:= true],
        %%io:format("Path: ~p, A: ~p~n", [Path, A]), 
        case A of
            [] ->   %%Base case, i.e. folder has no sub-folders -> stop here
                    {PATH, []}; 
             _ ->   %%Recursive case, i.e. folder has sub-folders -> call @folders
                    {PATH, [folders(PATH ++ "/" ++ H2) || H2 <- A]}
        end.
    

    出于一致性原因,您需要调用主函数末尾不带正斜杠,因为这将添加到函数本身中。

    Folders = folders("C:/Users/David/test"). %% <- without forward slash
    

    下面的辅助函数 pretty_print 可用于可视化 Erlang shell 上的输出

    完整代码:

    -export([folders/1]).
    -export([main/0]).
    
    main() -> 
        Folders = folders("C:/Users/David/test"),
        pretty_print(Folders, 0),
        ok.
        
    folders(PATH) ->
        {_, DD} = file:list_dir(PATH), 
        A = [H || H <- DD, filelib:is_dir(PATH ++ "/" ++ H) =:= true], %%please note the "/" is added here
        %%io:format("Path: ~p, A: ~p~n", [Path, A]), 
        case A of
            [] ->   %%Base case, i.e. folder has no sub-folders -> stop here
                    {PATH, []}; 
             _ ->   %%Recursive case, i.e. folder has sub-folders -> call @folders
                    {PATH, [folders(PATH ++ "/" ++ H2) || H2 <- A]}
        end.
    
    pretty_print(Folders, Depth) ->
        {CurrrentFolder, ListSubfolders} = Folders,
        SignTemp = lists:duplicate(Depth, "-"),
        case Depth of
            0 -> Sign = SignTemp;
            _ -> Sign = "|" ++ SignTemp
        end,
        io:format("~s~s~n", [Sign, CurrrentFolder]),
        [pretty_print(Subfolder, Depth+1) || Subfolder <- ListSubfolders].
    

    【讨论】:

      猜你喜欢
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 2021-07-09
      • 2014-10-02
      相关资源
      最近更新 更多