Elixir 带长生不老药的深层递归
我正在开发一个文件系统Elixir 带长生不老药的深层递归,elixir,Elixir,我正在开发一个文件系统seaveedfs。我们在上面用适当的目录结构保存了文件,如server/camera\u id/snapshots/recordings/year 我正在尝试删除年下的空文件夹 def clean do 摄像机= 摄像机 |>预加载(:所有者) |>订购人(描述::创建地点) |>Evercam.Repo.all() 年份=[“2015年”、“2016年”、“2017年”、“2018年”、“2019年”] 服务器=[@seaweedfs\u新、@seaweedfs\u旧、
seaveedfs
。我们在上面用适当的目录结构保存了文件,如server
/camera\u id
/snapshots
/recordings
/year
我正在尝试删除年下的空文件夹
def clean do
摄像机=
摄像机
|>预加载(:所有者)
|>订购人(描述::创建地点)
|>Evercam.Repo.all()
年份=[“2015年”、“2016年”、“2017年”、“2018年”、“2019年”]
服务器=[@seaweedfs\u新、@seaweedfs\u旧、@seaweedfs\u旧]
枚举每个(摄像头,fn摄像头->
枚举每个(服务器,fn服务器->
类型=海景类型(服务器)
属性=海藻属性(服务器)
url=服务器“/#{camera.exid}/snapshots/recordings/”
每(年,fn年->
最终url=url年份“/”
从seaweedfs请求(最终url、类型、属性)
(完)
(完)
(完)
结束
当最终请求在request\u from\u seaveedfs(最终url、类型、属性)
它要么给出这样的列表,[“01”、“02”、“03”]
,要么给出[]
在[]
的情况下,我只是删除完整的树作为
url=server/gaol-yard/snapshots/recordings/2016/?recursive=true
hackney=[pool::SeaveedFS\u下载\u pool,记录超时:30\u 000]
HTTPoison.delete!(“{url}?recursive=true”,[],hackney:hackney)
但我想更深入,如果结果不是[]
,那么我想进入几个月,比如
months=[“01”、“02”、“03”]
final_url=url year”/“{moth value from the list}”
每个月都有连续的几天,接下来的几天有小时
我想用递归检查所有这些,比如如果最后一级或任何一级为空,则删除一棵树
例如,如果相机具有、年、月、日和小时,但在最后一级,如果小时给出[]
删除整个树
这可以通过
Enum来实现。如果每次我没有得到[]
的话,每次都要循环并一直到最后一级,并且上面写着[]
删除它,但是可以通过更编程的方式实现吗?用递归而不是这么多的each?任何帮助都会有帮助的,谢谢编辑:误解的问题
因此,如果您想使用递归生成组合,我想您可以将参数(摄影机、服务器、年份)作为嵌套列表传递,并递归地构造组合(使用第一个列表(摄影机),并通过传递其余列表(服务器和年份)等来构造列表)
这样做的好处是,您可以传递任意数量的项目或列表,并且当您要在url中添加另一个级别时,它将构造组合,而不是再添加一个级别的Enum.each
defmodule Test do
def perm(input, acc \\ [])
def perm([], acc), do: acc
def perm([first_arr | rest_arr], acc) do
first_arr
|> Enum.map(fn val ->
perm(rest_arr, [val | acc])
end)
end
def flat([fst | rst]) when is_list(fst) do
case fst do
[fst1 | _rst1] when is_list(fst1) -> flat(fst ++ rst)
_ -> [fst] ++ flat(rst)
end
end
def flat(other), do: other
end
cameras = ["gaol-yard", "gaol-yard-1", "gaol-yard-2"]
years = ["2015", "2016", "2017", "2018", "2019"]
servers = ["seaweedfs_new", "seaweedfs_old", "seaweedfs_oldest"]
# input = [[1,2,3], [:a,:b,:c], [5.0, 6.0, 7.0]]
[cameras, years, servers] \
|> Test.perm() \
|> Test.flat \
|> Enum.map(&Enum.reverse/1)
这应该会产生类似于
[
["gaol-yard", "2015", "seaweedfs_new"],
["gaol-yard", "2015", "seaweedfs_old"],
["gaol-yard", "2015", "seaweedfs_oldest"],
["gaol-yard", "2016", "seaweedfs_new"],
["gaol-yard", "2016", "seaweedfs_old"],
["gaol-yard", "2016", "seaweedfs_oldest"],
...
"gaol-yard-1", "2015", "seaweedfs_old"],
["gaol-yard-1", "2015", "seaweedfs_oldest"],
["gaol-yard-1", "2016", "seaweedfs_new"],
...
["gaol-yard-2", "2019", "seaweedfs_new"],
["gaol-yard-2", "2019", "seaweedfs_old"],
["gaol-yard-2", "2019", "seaweedfs_oldest"]
]
您可以将每个连接到一个字符串中编辑:误解的问题
因此,如果您想使用递归生成组合,我想您可以将参数(摄影机、服务器、年份)作为嵌套列表传递,并递归地构造组合(使用第一个列表(摄影机),并通过传递其余列表(服务器和年份)等来构造列表)
这样做的好处是,您可以传递任意数量的项目或列表,并且当您要在url中添加另一个级别时,它将构造组合,而不是再添加一个级别的Enum.each
defmodule Test do
def perm(input, acc \\ [])
def perm([], acc), do: acc
def perm([first_arr | rest_arr], acc) do
first_arr
|> Enum.map(fn val ->
perm(rest_arr, [val | acc])
end)
end
def flat([fst | rst]) when is_list(fst) do
case fst do
[fst1 | _rst1] when is_list(fst1) -> flat(fst ++ rst)
_ -> [fst] ++ flat(rst)
end
end
def flat(other), do: other
end
cameras = ["gaol-yard", "gaol-yard-1", "gaol-yard-2"]
years = ["2015", "2016", "2017", "2018", "2019"]
servers = ["seaweedfs_new", "seaweedfs_old", "seaweedfs_oldest"]
# input = [[1,2,3], [:a,:b,:c], [5.0, 6.0, 7.0]]
[cameras, years, servers] \
|> Test.perm() \
|> Test.flat \
|> Enum.map(&Enum.reverse/1)
这应该会产生类似于
[
["gaol-yard", "2015", "seaweedfs_new"],
["gaol-yard", "2015", "seaweedfs_old"],
["gaol-yard", "2015", "seaweedfs_oldest"],
["gaol-yard", "2016", "seaweedfs_new"],
["gaol-yard", "2016", "seaweedfs_old"],
["gaol-yard", "2016", "seaweedfs_oldest"],
...
"gaol-yard-1", "2015", "seaweedfs_old"],
["gaol-yard-1", "2015", "seaweedfs_oldest"],
["gaol-yard-1", "2016", "seaweedfs_new"],
...
["gaol-yard-2", "2019", "seaweedfs_new"],
["gaol-yard-2", "2019", "seaweedfs_old"],
["gaol-yard-2", "2019", "seaweedfs_oldest"]
]
您可以将每个连接到一个字符串中这里有一种方法。将当前函数更改为使用已知的年数调用recursive\u delete
:
Enum.each(cameras, fn camera ->
Enum.each(servers, fn server ->
type = seaweefs_type(server)
attribute = seaweedfs_attribute(server)
url = server <> "/#{camera.exid}/snapshots/recordings/"
recursive_delete(years, url, type, attribute)
end)
end)
Enum.each(摄像机,fn摄像机->
枚举每个(服务器,fn服务器->
类型=海景类型(服务器)
属性=海藻属性(服务器)
url=服务器“/#{camera.exid}/snapshots/recordings/”
递归删除(年份、url、类型、属性)
(完)
(完)
然后:
def recursive_delete([], _, _, _), do: :done
def recursive_delete(entries, url, type, attribute) do
Enum.each(entries, fn entry ->
entry_url = url <> entry <> "/"
entry_url
|> request_from_seaweedfs(type, attribute)
|> recursive_delete(entry_url, type, attribute)
end)
end
def recursive_delete([],,,,,,),do::done
def recursive_delete(条目、url、类型、属性)do
枚举每个(条目,fn条目->
条目\ url=url条目“/”
输入地址
|>从seaweedfs请求(类型、属性)
|>递归删除(条目、url、类型、属性)
(完)
结束
这里有一种方法。将当前函数更改为使用已知的年数调用recursive\u delete
:
Enum.each(cameras, fn camera ->
Enum.each(servers, fn server ->
type = seaweefs_type(server)
attribute = seaweedfs_attribute(server)
url = server <> "/#{camera.exid}/snapshots/recordings/"
recursive_delete(years, url, type, attribute)
end)
end)
Enum.each(摄像机,fn摄像机->
枚举每个(服务器,fn服务器->
类型=海景类型(服务器)
属性=海藻属性(服务器)
url=服务器“/#{camera.exid}/snapshots/recordings/”
递归删除(年份、url、类型、属性)
(完)
(完)
然后:
def recursive_delete([], _, _, _), do: :done
def recursive_delete(entries, url, type, attribute) do
Enum.each(entries, fn entry ->
entry_url = url <> entry <> "/"
entry_url
|> request_from_seaweedfs(type, attribute)
|> recursive_delete(entry_url, type, attribute)
end)
end
def recursive_delete([],,,,,,),do::done
def recursive_delete(条目、url、类型、属性)do
枚举每个(条目,fn条目->
条目\ url=url条目“/”
输入地址
|>从seaweedfs请求(类型、属性)
|>递归删除(条目、url、类型、属性)
(完)
结束
这是对枚举的嵌套调用。每个/2
都可以替换为可读性更好的for
宏。我更喜欢1)使用case语句分别为每个步骤编写函数,说明如何执行其他操作2)然后在不使用列表时对每个函数进行模式匹配empty@ZubairNabi检查Jose的回答:)嵌套调用到Enum。每个/2
都可以替换为可读性更好的for
宏。我更喜欢1)使用case语句分别为每个步骤编写函数,说明如何执行其他操作2)然后在不使用列表时对每个函数进行模式匹配empty@ZubairNabi查查何塞的回答:)你实际上没有回答这个问题)该死的…),所以,如果最下面的目录是空的,从上面删除整个目录?是的,它也不是实际的目录:)它只是HTTP URL,它是一个文件系统