我有一个列表:
["storage.pages/4532.1.html",
"storage.pages/4532.12.html",
"storage.pages/4532.2.html",
"storage.pages/4532.3.html",
"storage.pages/4532.4.html",
"storage.pages/4532.5.html"]
我想做这样的事情:
last_filename(PageId)->
Files1 = filelib:wildcard("storage.pages/" ++ wf:to_list(PageId) ++ ".*.html"),
hd(lists:reverse(lists:sort(Files1))).
目前返回"storage.pages/4532.5.html"
,但我希望它返回"storage.pages/4532.12.html"
。
我需要对函数进行哪些调整,以使其始终返回列表中基名中具有最高后缀编号的元素?
干杯!
答案 0 :(得分:3)
高效的解决方案(在Perl世界中被称为Schwartzian transform):
L = ["storage.pages/4532.1.html",
"storage.pages/4532.12.html",
"storage.pages/4532.2.html",
"storage.pages/4532.3.html",
"storage.pages/4532.4.html",
"storage.pages/4532.5.html"].
element(2, lists:max([ {list_to_integer(lists:last(string:tokens(filename:basename(X, ".html"), "."))), X} || X <- L])).
作为模块中的功能
last_filename(PageId) ->
Files = filelib:wildcard("storage.pages/" ++ wf:to_list(PageId) ++ ".*.html"),
FilesWVersion = [ {version(FN), FN} || FN <- Files ],
{_, LF} = lists:max(FilesWVersion),
LF.
version(FileName) ->
BN = filename:basename(X, ".html"),
VS = lists:last(string:tokens(BN, ".")),
list_to_integer(VS).
答案 1 :(得分:1)
在这种情况下,您不需要将字符串的一部分转换为数字。只是首先比较字符串的长度。
L=["storage.pages/4532.1.html",
"storage.pages/4532.12.html",
"storage.pages/4532.2.html",
"storage.pages/4532.3.html",
"storage.pages/4532.4.html",
"storage.pages/4532.5.html"].
RComp = fun(X,Y)->length(X) > length(Y) orelse X > Y end.
hd(lists:sort(RComp,L)).
输出:
“ storage.pages / 4532.12.html”
答案 2 :(得分:0)
我这样解决了,但欢迎提出改进建议:
last_filename(Page)->
Files1 = filelib:wildcard("storage.pages/" ++ wf:to_list(Page#page.id) ++ ".*.html"),
Files2 = lists:sort(fun(X, Y) ->
X1 = wf:to_integer(lists:nth(2, lists:reverse(string:split(X, ".", all)))),
Y1 = wf:to_integer(lists:nth(2, lists:reverse(string:split(Y, ".", all)))),
X1 > Y1
end, Files1),
hd(Files2).