Erlang应该如何过滤列表中的元素,并添加标点和[]?
Posted
技术标签:
【中文标题】Erlang应该如何过滤列表中的元素,并添加标点和[]?【英文标题】:How should Erlang filter the elements in the list, and add punctuation and []? 【发布时间】:2021-03-13 00:05:50 【问题描述】:-module(solarSystem).
-export([process_csv/1, is_numeric/1, parseALine/2, parse/1, expandT/1, expandT/2,
parseNames/1]).
parseALine(false, T) ->
T;
parseALine(true, T) ->
T.
parse([Name, Colour, Distance, Angle, AngleVelocity, Radius, "1" | T]) ->
T;%Where T is a list of names of other objects in the solar system
parse([Name, Colour, Distance, Angle, AngleVelocity, Radius | T]) ->
T.
parseNames([H | T]) ->
H.
expandT(T) ->
T.
expandT([], Sep) ->
[];
expandT([H | T], Sep) ->
T.
% https://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Erlang
is_numeric(L) ->
S = trim(L, ""),
Float = (catch erlang:list_to_float(S)),
Int = (catch erlang:list_to_integer(S)),
is_number(Float) orelse is_number(Int).
trim(A) ->
A.
trim([], A) ->
A;
trim([32 | T], A) ->
trim(T, A);
trim([H | T], A) ->
trim(T, A ++ [H]).
process_csv(L) ->
X = parse(L),
expandT(X).
问题是它会在我的模块中调用process_csv/1
函数main
,L
会是这样的文件:
[["name "," col"," dist"," a"," angv"," r "," ..."],["apollo11 ","white"," 0.1"," 0"," 77760"," 0.15"]]
或者像这样:
["planets ","earth","venus "]
或者像这样:
["a","b"]
我需要显示如下:
apollo11 =["white", 0.1, 0, 77760, 0.15,[]];
Planets =[earth,venus]
a,b
[[59],[97],[44],[98]]
我的问题是,无论怎么修改,都只能显示一部分,没有符号。列表不能分割,所以我找不到方法。 另外,由于 Erlang 是一种小众编程语言,我什至在网上都找不到示例。 那么,任何人都可以帮助我吗?非常感谢。 另外,我被限制使用递归。
【问题讨论】:
我打算编辑您的问题以使其更清晰。如果我正确理解了您的问题,请告诉我。 【参考方案1】:我认为第一个问题是很难将您正在尝试实现的目标与您的代码到目前为止所说的内容联系起来。因此,此反馈可能不是您正在寻找的,但可能会提供一些想法。 让我们将问题分解为共同的元素:(1) 输入、(2) 过程和 (3) 输出。
输入 您提到 L 将是一个文件,但我假设它是文件中的 行,其中每一行都可以是 3(三)个样本之一。在这方面,样本也没有一致的模式。为此,我们可以构建一个函数,将文件的每一行转换为 Erlang 术语,并将结果传递给下一步。
流程
该问题也没有提到解析/处理输入的具体逻辑。您似乎也关心数据类型,因此我们将相应地转换并显示结果。 Erlang 作为函数式语言自然会处理列表,所以在大多数情况下我们需要在lists
模块上使用函数
输出
您没有特别提到要在哪里显示结果(输出文件、屏幕/erlang shell 等),所以假设您只想在标准输出/erlang shell 中显示它。
示例文件内容test1.txt
(请注意每行末尾的点)
[["name "," col"," dist"," a"," angv"," r "],["apollo11 ","white","0.1"," 0"," 77760"," 0.15"]].
["planets ","earth","venus "].
["a","b"].
如何运行:solarSystem:process_file("/Users/macbook/Documents/test1.txt").
示例结果:
(dev01@Macbooks-MacBook-Pro-3)3> solarSystem:process_file("/Users/macbook/Documents/test1.txt").
apollo11 = ["white",0.1,0,77760,0.15]
planets = ["earth","venus"]
a = ["b"]
Done processing 3 line(s)
ok
模块代码:
-module(solarSystem).
-export([process_file/1]).
-export([process_line/2]).
-export([format_item/1]).
%%This is the main function, input is file full path
%%Howto call: solarSystem:process_file("file_full_path").
process_file(Filename) ->
%%Use file:consult to convert the file content into erlang terms
%%File content is a dot (".") separated line
StatusOpen, Result = file:consult(Filename),
case StatusOpen of
ok ->
%%Result is a list and therefore each element must be handled using lists function
Ctr = lists:foldl(fun process_line/2, 0, Result),
io:format("Done processing ~p line(s) ~n", [Ctr]);
_ -> %%This is for the case where file not available
io:format("Error converting file ~p due to '~p' ~n", [Filename, Result])
end.
process_line(Term, CtrIn) ->
%%Assume there are few possibilities of element. There are so many ways to process the data as long as the input pattern is clear.
%%We basically need to identify all possibilities and handle them accordingly.
%%Of course there are smarter (dynamic) ways to handle them, but below may give you some ideas.
case Term of
%%1. This is to handle this pattern -> [["name "," col"," dist"," a"," angv"," r "],["apollo11 ","white"," 0.1"," 0"," 77760"," 0.15"]]
[[_, _, _, _, _, _], [Name | OtherParams]] ->
%%At this point, Name = "apollo11", OtherParamsList = ["white"," 0.1"," 0"," 77760"," 0.15"]
OtherParamsFmt = lists:map(fun format_item/1, OtherParams),
%%Display the result to standard output
io:format("~s = ~p ~n", [string:trim(Name), OtherParamsFmt]);
%%2. This is to handle this pattern -> ["planets ","earth","venus "]
[Name | OtherParams] ->
%%At this point, Name = "planets ", OtherParamsList = ["earth","venus "]
OtherParamsFmt = lists:map(fun format_item/1, OtherParams),
%%Display the result to standard output
io:format("~s = ~p ~n", [string:trim(Name), OtherParamsFmt]);
%%3. Other cases
_ ->
%%Display the warning to standard output
io:format("Unknown pattern ~p ~n", [Term])
end,
CtrIn + 1.
%%This is to format the string accordingly
format_item(Str) ->
StrTrim = string:trim(Str), %%first, trim it
format_as_needed(StrTrim).
format_as_needed(Str) ->
Float = (catch erlang:list_to_float(Str)),
case Float of
'EXIT', _ -> %%It is not a float -> check if it is an integer
Int = (catch erlang:list_to_integer(Str)),
case Int of
'EXIT', _ -> %%It is not an integer -> return as is (string)
Str;
_ -> %%It is an int
Int
end;
_ -> %%It is a float
Float
end.
【讨论】:
以上是关于Erlang应该如何过滤列表中的元素,并添加标点和[]?的主要内容,如果未能解决你的问题,请参考以下文章