给定一个txt日志文件,格式为:
USER_A timestamp1 otherstuff
USER_B timestamp2 otherstuff
USER_C timestamp3 otherstuff
USER_A timestamp4 otherstuff
USER_A timestamp5 otherstuff
USER_C timestamp6 otherstuff
USER_B timestamp7 otherstuff
您如何计算erlang中不同唯一身份用户的数量?我正在考虑逐行读取文件并使用proplists模块。每个用户都是一个键,其值将是出现的次数。读完文件后,我打电话给:
length(proplists:get_keys(List)).
这是实现我的结果的正确方法吗?
答案 0 :(得分:4)
我也会使用sets模块,因为它既快又且不包含重复项。
以下代码应该完成这项工作:
{ok,Bin} = file:read_file("test"),
List = binary_to_list(Bin),
Usernames = [hd(string:tokens(X," ")) || X <- string:tokens(List,[$\n])],
sets:size(sets:from_list(Usernames)).
编辑:我删除了单行,因为它没有添加任何值
答案 1 :(得分:3)
使用sets
模块中的集合来存储用户名然后使用sets:size/1
可能更合适。
答案 2 :(得分:1)
日志文件通常很大,因此请考虑在递归函数中一次使用一行:
% Count the number of distinct users in the file named Filename
count_users(Filename) ->
{ok, File} = file:open(Filename, [read, raw, read_ahead]),
Usernames = usernames(File, sets:new()),
file:close(File),
sets:size(Usernames).
% Add all users in File, from the current file pointer position and forward,
% to Set.
% Side-effects: File is read and the file pointer is moved to the end.
usernames(File, Set) ->
case file:read_line(File) of
{ok, Line} ->
Username = hd(string:tokens(Line, " ")),
usernames(File, sets:add_element(Username, Set));
eof ->
Set
end.
您只需将其称为:count_users("logfile")
。
请注意usernames/2
必须tail recursive才能有效运作。否则它会消耗更多的内存。