Erlang-根据扩展名前的后缀编号对文件列表进行排序

时间:2018-07-10 22:23:46

标签: erlang

我有一个列表:

["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"

我需要对函数进行哪些调整,以使其始终返回列表中基名中具有最高后缀编号的元素?

干杯!

3 个答案:

答案 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).