如何遍历 Erlang 中的目录以仅获取文件夹?
How to walk through directory in Erlang to take only folders?
-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"}},
]
几件事:
- 这2个调用可以简化。
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],
- 在表示上,子文件夹应该是列表格式,而不是元组格式。如果它们是元组,将很难处理。
示例结构:
{Folder, [Subfolder1, Subfolder2, ...]}
,其中 SubfolderX
将具有相同的定义和结构,递归地。
- 文件夹就像一棵树,这里需要递归调用。希望您已经熟悉这个概念。下面是一种使用列表推导来做到这一点的方法——无论如何还有其他方法,例如通过使用
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].
-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"}},
]
几件事:
- 这2个调用可以简化。
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],
- 在表示上,子文件夹应该是列表格式,而不是元组格式。如果它们是元组,将很难处理。
示例结构:
{Folder, [Subfolder1, Subfolder2, ...]}
,其中SubfolderX
将具有相同的定义和结构,递归地。 - 文件夹就像一棵树,这里需要递归调用。希望您已经熟悉这个概念。下面是一种使用列表推导来做到这一点的方法——无论如何还有其他方法,例如通过使用
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].